Disabled external gits

This commit is contained in:
2022-04-07 18:46:57 +02:00
parent 88cb3426ad
commit 15e7120d6d
5316 changed files with 4563444 additions and 6 deletions

View File

@@ -0,0 +1,344 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks. Getting Started Samples</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,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
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks.<br>Getting Started Samples</h1>
</div>
<p>
This directory contains the examples referenced by the Intel&reg; Threading Building Blocks <a href="http://software.intel.com/en-us/tbb-tutorial">Getting&nbsp;Started&nbsp;Guide</a>.
</p>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="sub_string_finder/readme.html">sub_string_finder</a>
<dd>Finds largest matching substrings.
</dl>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a>
<hr>
<div class="changes">
<div class="h3-alike">Legal Information:</div>
<input type="checkbox">
<div class="show-hide">
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,55 @@
# Copyright (c) 2005-2020 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.
# Common Makefile that builds and runs examples.
PROG=sub_string_finder_extended
ARGS=
LIGHT_PROG=sub_string_finder
# The C++ compiler options
# Trying to find if icl.exe is set
CXX1 = $(TBB_CXX)-
CXX2 = $(CXX1:icl.exe-=icl.exe)
CXX = $(CXX2:-=cl.exe)
offload1 = $(offload)+
OFFLOADFLAGS1 = $(offload1:mic+=/Qoffload-arch=mic)
OFFLOADFLAGS2 = $(OFFLOADFLAGS1:mic-avx512+=/Qoffload-arch=mic-avx512)
offload2 = $(offload:mic-avx512=mic)
OFFLOADFLAGS = $(OFFLOADFLAGS2:+=) $(offload2:mic=/D__TBB_MIC_OFFLOAD /Qdiag-disable:3335,3440,3441)
MYCXXFLAGS = /EHsc /W3 /nologo /D _CONSOLE /D _MBCS /D WIN32 $(OFFLOADFLAGS) $(CXXFLAGS)
MYLDFLAGS =/INCREMENTAL:NO /NOLOGO /DEBUG /FIXED:NO $(LDFLAGS)
TBB_MIC_LIB = $(offload2:mic=/Qtbb)
TBB_DEBUG_MIC_LIB = $(offload2:mic=/Qoffload-option,mic,link,"-ltbb_debug")
all: release test
release: compiler_check
$(CXX) sub_string_finder.cpp /MD /O2 /D NDEBUG $(MYCXXFLAGS) $(TBB_MIC_LIB) /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:sub_string_finder.exe
$(CXX) sub_string_finder_extended.cpp /MD /O2 /D NDEBUG $(MYCXXFLAGS) $(TBB_MIC_LIB) /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:sub_string_finder_extended.exe
$(CXX) sub_string_finder_pretty.cpp /MD /O2 /D NDEBUG $(MYCXXFLAGS) $(TBB_MIC_LIB) /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:sub_string_finder_pretty.exe
debug: compiler_check
$(CXX) sub_string_finder.cpp /MDd /Od /Zi /D TBB_USE_DEBUG /D _DEBUG $(MYCXXFLAGS) $(TBB_DEBUG_MIC_LIB) /link tbb_debug.lib $(LIBS) $(MYLDFLAGS) /OUT:sub_string_finder.exe
$(CXX) sub_string_finder_extended.cpp /MDd /Od /Zi /D TBB_USE_DEBUG /D _DEBUG $(MYCXXFLAGS) $(TBB_DEBUG_MIC_LIB) /link tbb_debug.lib $(LIBS) $(MYLDFLAGS) /OUT:sub_string_finder_extended.exe
$(CXX) sub_string_finder_pretty.cpp /MDd /Od /Zi /D TBB_USE_DEBUG /D _DEBUG $(MYCXXFLAGS) $(TBB_DEBUG_MIC_LIB) /link tbb_debug.lib $(LIBS) $(MYLDFLAGS) /OUT:sub_string_finder_pretty.exe
clean:
@cmd.exe /C del sub_string_finder*.exe *.obj *.?db *.manifest
test:
$(PROG) $(ARGS)
light_test:
$(LIGHT_PROG) $(ARGS)
compiler_check:
@echo compiler_test>compiler_test && @$(CXX) /E compiler_test >nul 2>&1 || echo "$(CXX) command not found. Check if CXX=$(CXX) is set properly"
@cmd.exe /C del compiler_test

View File

@@ -0,0 +1,416 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks. Sub_string_finder sample</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,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
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks.<br>Sub_string_finder sample</h1>
</div>
<p>
A simple example that uses the parallel_for template in a substring matching program.
The Intel&reg; Threading Building Blocks <a href="http://software.intel.com/en-us/tbb-tutorial">Getting&nbsp;Started&nbsp;Guide</a> describes this example.
<br><br>
For each position
in a string, the program displays the length of the largest matching substring elsewhere in the string.
The program also displays the location of a largest match for each position. Consider the string "babba"
as an example. Starting at position 0, "ba" is the largest substring with a match elsewhere in the
string (position 3).
<br><br>
The code located in the <a href="sub_string_finder_extended.cpp">sub_string_finder_extended.cpp</a> file
demonstrates offload programming for Intel&reg; Many Integrated Core (Intel&reg; MIC) Architecture (see <a href="../../index.html">build instructions</a>).
</p>
<div class="changes">
<div class="h3-alike">System Requirements</div>
<input type="checkbox">
<div class="show-hide">
<p>
For the most up to date system requirements, see the <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a>
</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Files</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="sub_string_finder.cpp">sub_string_finder.cpp</a>
<dd>The example as it appears in the Getting Started Guide.
<dt><a href="sub_string_finder_extended.cpp">sub_string_finder_extended.cpp</a>
<dd>An example similar to the one in the Getting Started Guide, but with an added sequential
implementation, and with an offload region added that can be executed on Intel&reg; MIC Architecture based coprocessor.
The three implementations are timed, by using tick_count,
and the speedup of the parallel version and
the speedup of the parallel version and, if applicable, the offload version is calculated and displayed.
<dt><a href="sub_string_finder_pretty.cpp">sub_string_finder_pretty.cpp</a>
<dd>An example similar to the one in the Getting Started Guide, but with more attractive printing of the results.
<dt><a href="Makefile">Makefile</a>
<dd>Makefile for building the example.
</dl>
</div>
</div>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="msvs/">msvs</a>
<dd>Contains Microsoft* Visual Studio* workspace for building and running the example (Windows* systems only).
<dt><a href="xcode/">xcode</a>
<dd>Contains Xcode* IDE workspace for building and running the example (macOS* systems only).
</dl>
<p>For information about the minimum supported version of IDE, see <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a></p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Build instructions</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<p>General build directions can be found <a href="../../index.html">here</a>.</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Usage</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><tt>sub_string_finder</tt>
<dd>Runs the example as it appears in the Getting Started Guide.
<dt><tt>sub_string_finder_pretty</tt>
<dd>Runs the similar example with more attractive printing of the results.
<dt><tt>sub_string_finder_extended</tt>
<dd>Runs the example extended with a sequential implementation and an offload region that can be executed on Intel&reg; MIC Architecture based coprocessor.
<dt>To run a short version of this example, e.g., for use with Intel&reg; Threading Tools:
<dd>Build a <i>debug</i> version of the <tt>sub_string_finder_pretty</tt> example
(see the <a href="../../index.html">build instructions</a>).
<br>Run it, e.g., <tt>sub_string_finder_pretty</tt>.
</dl>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a>
<hr>
<div class="changes">
<div class="h3-alike">Legal Information</div>
<input type="checkbox">
<div class="show-hide">
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,74 @@
/*
Copyright (c) 2005-2020 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 <iostream>
#include <string>
#include <vector>
#include <algorithm> //std::max
#include "tbb/parallel_for.h"
#include "tbb/blocked_range.h"
static const std::size_t N = 23;
class SubStringFinder {
const std::string &str;
std::vector<std::size_t> &max_array;
std::vector<std::size_t> &pos_array;
public:
void operator() ( const tbb::blocked_range<std::size_t> &r ) const {
for (std::size_t i = r.begin(); i != r.end(); ++i) {
std::size_t max_size = 0, max_pos = 0;
for (std::size_t j = 0; j < str.size(); ++j) {
if (j != i) {
std::size_t limit = str.size()-(std::max)(i,j);
for (std::size_t k = 0; k < limit; ++k) {
if (str[i + k] != str[j + k])
break;
if (k > max_size) {
max_size = k;
max_pos = j;
}
}
}
}
max_array[i] = max_size;
pos_array[i] = max_pos;
}
}
SubStringFinder( const std::string &s, std::vector<std::size_t> &m, std::vector<std::size_t> &p ) :
str(s), max_array(m), pos_array(p) { }
};
int main() {
std::string str[N] = { std::string("a"), std::string("b") };
for (std::size_t i = 2; i < N; ++i)
str[i] = str[i-1]+str[i-2];
std::string &to_scan = str[N-1];
const std::size_t num_elem = to_scan.size();
std::vector<std::size_t> max(num_elem);
std::vector<std::size_t> pos(num_elem);
tbb::parallel_for( tbb::blocked_range<std::size_t>( 0, num_elem ),
SubStringFinder( to_scan, max, pos ) );
for (std::size_t i = 0; i < num_elem; ++i)
std::cout << " " << max[i] << "(" << pos[i] << ")" << std::endl;
return 0;
}

View File

@@ -0,0 +1,162 @@
/*
Copyright (c) 2005-2020 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.
*/
#if __TBB_MIC_OFFLOAD
#pragma offload_attribute (push,target(mic))
#endif // __TBB_MIC_OFFLOAD
#include <iostream>
#include <string>
#include <vector>
#include <algorithm> //std::max
#include "tbb/parallel_for.h"
#include "tbb/blocked_range.h"
#include "tbb/tick_count.h"
#if __TBB_MIC_OFFLOAD
#pragma offload_attribute (pop)
class __declspec(target(mic)) SubStringFinder;
#endif // __TBB_MIC_OFFLOAD
static const std::size_t N = 22;
void SerialSubStringFinder ( const std::string &str, std::vector<std::size_t> &max_array, std::vector<std::size_t> &pos_array ) {
for (std::size_t i = 0; i < str.size(); ++i) {
std::size_t max_size = 0, max_pos = 0;
for (std::size_t j = 0; j < str.size(); ++j)
if (j != i) {
std::size_t limit = str.size()-(std::max)(i,j);
for (std::size_t k = 0; k < limit; ++k) {
if (str[i + k] != str[j + k])
break;
if (k > max_size) {
max_size = k;
max_pos = j;
}
}
}
max_array[i] = max_size;
pos_array[i] = max_pos;
}
}
class SubStringFinder {
const char *str;
const std::size_t len;
std::size_t *max_array;
std::size_t *pos_array;
public:
void operator() ( const tbb::blocked_range<std::size_t>& r ) const {
for (std::size_t i = r.begin(); i != r.end(); ++i) {
std::size_t max_size = 0, max_pos = 0;
for (std::size_t j = 0; j < len; ++j) {
if (j != i) {
std::size_t limit = len-(std::max)(i,j);
for (std::size_t k = 0; k < limit; ++k) {
if (str[i + k] != str[j + k])
break;
if (k > max_size) {
max_size = k;
max_pos = j;
}
}
}
}
max_array[i] = max_size;
pos_array[i] = max_pos;
}
}
// We do not use std::vector for compatibility with offload execution
SubStringFinder( const char *s, const std::size_t s_len, std::size_t *m, std::size_t *p ) :
str(s), len(s_len), max_array(m), pos_array(p) { }
};
int main() {
using namespace tbb;
std::string str[N] = { std::string("a"), std::string("b") };
for (std::size_t i = 2; i < N; ++i)
str[i] = str[i-1]+str[i-2];
std::string &to_scan = str[N-1];
const std::size_t num_elem = to_scan.size();
std::vector<std::size_t> max1(num_elem);
std::vector<std::size_t> pos1(num_elem);
std::vector<std::size_t> max2(num_elem);
std::vector<std::size_t> pos2(num_elem);
std::cout << " Done building string." << std::endl;
tick_count serial_t0 = tick_count::now();
SerialSubStringFinder( to_scan, max2, pos2 );
tick_count serial_t1 = tick_count::now();
std::cout << " Done with serial version." << std::endl;
tick_count parallel_t0 = tick_count::now();
parallel_for(blocked_range<std::size_t>(0, num_elem, 100),
SubStringFinder( to_scan.c_str(), num_elem, &max1[0], &pos1[0] ) );
tick_count parallel_t1 = tick_count::now();
std::cout << " Done with parallel version." << std::endl;
for (std::size_t i = 0; i < num_elem; ++i) {
if (max1[i] != max2[i] || pos1[i] != pos2[i]) {
std::cout << "ERROR: Serial and Parallel Results are Different!" << std::endl;
break;
}
}
std::cout << " Done validating results." << std::endl;
std::cout << "Serial version ran in " << (serial_t1 - serial_t0).seconds() << " seconds" << std::endl
<< "Parallel version ran in " << (parallel_t1 - parallel_t0).seconds() << " seconds" << std::endl
<< "Resulting in a speedup of " << (serial_t1 - serial_t0).seconds() / (parallel_t1 - parallel_t0).seconds() << std::endl;
#if __TBB_MIC_OFFLOAD
// Do offloadable version. Do the timing on host.
std::vector<std::size_t> max3(num_elem);
std::vector<std::size_t> pos3(num_elem);
std::size_t *max3_array = &max3[0]; // method data() for vector is not available in C++03
std::size_t *pos3_array = &pos3[0];
tick_count parallel_tt0 = tick_count::now();
const char *to_scan_str = to_scan.c_str(); // Offload the string as a char array.
#pragma offload target(mic) in(num_elem) in(to_scan_str:length(num_elem)) out(max3_array,pos3_array:length(num_elem))
{
parallel_for(blocked_range<std::size_t>(0, num_elem, 100),
SubStringFinder ( to_scan_str, num_elem, max3_array, pos3_array ) );
}
tick_count parallel_tt1 = tick_count::now();
std::cout << " Done with offloadable version." << std::endl;
// Do validation of offloadable results on host.
for (std::size_t i = 0; i < num_elem; ++i) {
if (max1[i] != max3[i] || pos1[i] != pos3[i]) {
std::cout << "ERROR: Serial and Offloadable Results are Different!" << std::endl;
break;
}
}
std::cout << " Done validating offloadable results." << std::endl;
std::cout << "Offloadable version ran in " << (parallel_tt1 - parallel_tt0).seconds() << " seconds" << std::endl
<< "Resulting in a speedup of " << (serial_t1 - serial_t0).seconds() / (parallel_tt1 - parallel_tt0).seconds()
<< " of offloadable version" << std::endl;
#endif // __TBB_MIC_OFFLOAD
return 0;
}

View File

@@ -0,0 +1,94 @@
/*
Copyright (c) 2005-2020 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 <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <algorithm> //std::max
#include "tbb/parallel_for.h"
#include "tbb/blocked_range.h"
static const std::size_t N = 9;
class SubStringFinder {
const std::string &str;
std::vector<std::size_t> &max_array;
std::vector<std::size_t> &pos_array;
public:
void operator() ( const tbb::blocked_range<std::size_t>& r ) const {
for (std::size_t i = r.begin(); i != r.end(); ++i) {
std::size_t max_size = 0, max_pos = 0;
for (std::size_t j = 0; j < str.size(); ++j) {
if (j != i) {
std::size_t limit = str.size()-(std::max)(i,j);
for (std::size_t k = 0; k < limit; ++k) {
if (str[i + k] != str[j + k])
break;
if (k+1 > max_size) {
max_size = k+1;
max_pos = j;
}
}
}
}
max_array[i] = max_size;
pos_array[i] = max_pos;
}
}
SubStringFinder( const std::string &s, std::vector<std::size_t> &m, std::vector<std::size_t> &p ) :
str(s), max_array(m), pos_array(p) { }
};
int main() {
using namespace tbb;
std::string str[N] = { std::string("a"), std::string("b") };
for (std::size_t i = 2; i < N; ++i)
str[i] = str[i-1]+str[i-2];
std::string &to_scan = str[N-1];
const std::size_t num_elem = to_scan.size();
std::cout << "String to scan: " << to_scan << std::endl;
std::vector<std::size_t> max( num_elem );
std::vector<std::size_t> pos( num_elem );
parallel_for( blocked_range<std::size_t>( 0, num_elem, 100 ),
SubStringFinder( to_scan, max, pos ) );
for (std::size_t i = 0; i < num_elem; ++i) {
for (std::size_t j = 0; j < num_elem; ++j) {
if (j >= i && j < i + max[i])
std::cout << "_";
else
std::cout << " ";
}
std::cout << std::endl << to_scan << std::endl;
for (std::size_t j = 0; j < num_elem; ++j) {
if (j >= pos[i] && j < pos[i] + max[i])
std::cout << "*";
else
std::cout << " ";
}
std::cout << std::endl;
}
return 0;
}

View File

@@ -0,0 +1,502 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
A1F593A60B8F042A00073279 /* sub_string_finder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1F593A50B8F042A00073279 /* sub_string_finder.cpp */; };
A1F594270B8F1F8100073279 /* sub_string_finder_extended.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1F594260B8F1F8100073279 /* sub_string_finder_extended.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
C3C5894D218B576600DAC94C /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.intel.compilers.icc.latest;
fileType = sourcecode.cpp;
isEditable = 1;
outputFiles = (
);
script = "# Type a script or drag a script file from your workspace to insert its path.\n";
};
C3C5894E218B57EA00DAC94C /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.intel.compilers.icc.latest;
fileType = sourcecode.cpp;
isEditable = 1;
outputFiles = (
);
script = "# Type a script or drag a script file from your workspace to insert its path.\n";
};
C3C5894F218B581400DAC94C /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.intel.compilers.icc.latest;
fileType = sourcecode.cpp;
isEditable = 1;
outputFiles = (
);
script = "# Type a script or drag a script file from your workspace to insert its path.\n";
};
/* End PBXBuildRule section */
/* Begin PBXCopyFilesBuildPhase section */
8DD76F690486A84900D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 12;
dstPath = "";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
A1F594140B8F1E2D00073279 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
A1F5941D0B8F1F2D00073279 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
8DD76F6C0486A84900D96B5E /* sub_string_finder */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sub_string_finder; sourceTree = BUILT_PRODUCTS_DIR; };
A1F593A50B8F042A00073279 /* sub_string_finder.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sub_string_finder.cpp; path = ../sub_string_finder.cpp; sourceTree = SOURCE_ROOT; };
A1F5940A0B8F1D8E00073279 /* sub_string_finder_pretty */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sub_string_finder_pretty; sourceTree = BUILT_PRODUCTS_DIR; };
A1F594110B8F1E0C00073279 /* sub_string_finder_pretty.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sub_string_finder_pretty.cpp; path = ../sub_string_finder_pretty.cpp; sourceTree = SOURCE_ROOT; };
A1F5941B0B8F1F0900073279 /* sub_string_finder_extended */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sub_string_finder_extended; sourceTree = BUILT_PRODUCTS_DIR; };
A1F594260B8F1F8100073279 /* sub_string_finder_extended.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sub_string_finder_extended.cpp; path = ../sub_string_finder_extended.cpp; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8DD76F660486A84900D96B5E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
A1F594080B8F1D8E00073279 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
A1F594190B8F1F0900073279 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
08FB7794FE84155DC02AAC07 /* sub_string_finder */ = {
isa = PBXGroup;
children = (
08FB7795FE84155DC02AAC07 /* Source */,
1AB674ADFE9D54B511CA2CBB /* Products */,
);
name = sub_string_finder;
sourceTree = "<group>";
};
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
A1F594260B8F1F8100073279 /* sub_string_finder_extended.cpp */,
A1F594110B8F1E0C00073279 /* sub_string_finder_pretty.cpp */,
A1F593A50B8F042A00073279 /* sub_string_finder.cpp */,
);
name = Source;
sourceTree = "<group>";
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8DD76F6C0486A84900D96B5E /* sub_string_finder */,
A1F5940A0B8F1D8E00073279 /* sub_string_finder_pretty */,
A1F5941B0B8F1F0900073279 /* sub_string_finder_extended */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8DD76F620486A84900D96B5E /* sub_string_finder */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "sub_string_finder" */;
buildPhases = (
8DD76F640486A84900D96B5E /* Sources */,
8DD76F660486A84900D96B5E /* Frameworks */,
8DD76F690486A84900D96B5E /* CopyFiles */,
);
buildRules = (
C3C5894F218B581400DAC94C /* PBXBuildRule */,
);
dependencies = (
);
name = sub_string_finder;
productInstallPath = "$(HOME)/bin";
productName = sub_string_finder;
productReference = 8DD76F6C0486A84900D96B5E /* sub_string_finder */;
productType = "com.apple.product-type.tool";
};
A1F594090B8F1D8E00073279 /* sub_string_finder_pretty */ = {
isa = PBXNativeTarget;
buildConfigurationList = A1F5940C0B8F1DB600073279 /* Build configuration list for PBXNativeTarget "sub_string_finder_pretty" */;
buildPhases = (
A1F594070B8F1D8E00073279 /* Sources */,
A1F594080B8F1D8E00073279 /* Frameworks */,
A1F594140B8F1E2D00073279 /* CopyFiles */,
);
buildRules = (
C3C5894E218B57EA00DAC94C /* PBXBuildRule */,
);
dependencies = (
);
name = sub_string_finder_pretty;
productName = sub_string_finder_pretty;
productReference = A1F5940A0B8F1D8E00073279 /* sub_string_finder_pretty */;
productType = "com.apple.product-type.tool";
};
A1F5941A0B8F1F0900073279 /* sub_string_finder_extended */ = {
isa = PBXNativeTarget;
buildConfigurationList = A1F5941F0B8F1F4E00073279 /* Build configuration list for PBXNativeTarget "sub_string_finder_extended" */;
buildPhases = (
A1F594180B8F1F0900073279 /* Sources */,
A1F594190B8F1F0900073279 /* Frameworks */,
A1F5941D0B8F1F2D00073279 /* CopyFiles */,
);
buildRules = (
C3C5894D218B576600DAC94C /* PBXBuildRule */,
);
dependencies = (
);
name = sub_string_finder_extended;
productName = sub_string_finder_extended;
productReference = A1F5941B0B8F1F0900073279 /* sub_string_finder_extended */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1000;
};
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "sub_string_finder" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,
);
mainGroup = 08FB7794FE84155DC02AAC07 /* sub_string_finder */;
projectDirPath = "";
projectRoot = "";
targets = (
A1F5941A0B8F1F0900073279 /* sub_string_finder_extended */,
A1F594090B8F1D8E00073279 /* sub_string_finder_pretty */,
8DD76F620486A84900D96B5E /* sub_string_finder */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
8DD76F640486A84900D96B5E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A1F593A60B8F042A00073279 /* sub_string_finder.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
A1F594070B8F1D8E00073279 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
A1F594180B8F1F0900073279 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A1F594270B8F1F8100073279 /* sub_string_finder_extended.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
A1F593C60B8F0E6E00073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = sub_string_finder;
ZERO_LINK = NO;
};
name = Debug64;
};
A1F593C70B8F0E6E00073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = sub_string_finder;
ZERO_LINK = NO;
};
name = Release64;
};
A1F593C80B8F0E6E00073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(TBBROOT)/include",
/opt/intel/tbb/include,
);
ICC_CXX_LANG_DIALECT = "c++11";
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
LIBRARY_SEARCH_PATHS = (
"$(TBBROOT)/lib",
/opt/intel/tbb/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
ONLY_ACTIVE_ARCH = YES;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-m64",
);
OTHER_LDFLAGS = (
"-m64",
"-ltbb_debug",
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Debug64;
};
A1F593C90B8F0E6E00073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(TBBROOT)/include",
/opt/intel/tbb/include,
);
ICC_CXX_LANG_DIALECT = "c++11";
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
LIBRARY_SEARCH_PATHS = (
"$(TBBROOT)/lib",
/opt/intel/tbb/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-m64",
);
OTHER_LDFLAGS = (
"-m64",
"-ltbb",
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Release64;
};
A1F5940E0B8F1DB600073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = sub_string_finder_pretty;
ZERO_LINK = NO;
};
name = Debug64;
};
A1F594100B8F1DB600073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = sub_string_finder_pretty;
ZERO_LINK = NO;
};
name = Release64;
};
A1F594210B8F1F4E00073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = sub_string_finder_extended;
ZERO_LINK = NO;
};
name = Debug64;
};
A1F594230B8F1F4E00073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = sub_string_finder_extended;
ZERO_LINK = NO;
};
name = Release64;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "sub_string_finder" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F593C60B8F0E6E00073279 /* Debug64 */,
A1F593C70B8F0E6E00073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "sub_string_finder" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F593C80B8F0E6E00073279 /* Debug64 */,
A1F593C90B8F0E6E00073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
A1F5940C0B8F1DB600073279 /* Build configuration list for PBXNativeTarget "sub_string_finder_pretty" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F5940E0B8F1DB600073279 /* Debug64 */,
A1F594100B8F1DB600073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
A1F5941F0B8F1F4E00073279 /* Build configuration list for PBXNativeTarget "sub_string_finder_extended" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F594210B8F1F4E00073279 /* Debug64 */,
A1F594230B8F1F4E00073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View File

@@ -0,0 +1,84 @@
@echo off
REM
REM Copyright (c) 2005-2020 Intel Corporation
REM
REM Licensed under the Apache License, Version 2.0 (the "License");
REM you may not use this file except in compliance with the License.
REM You may obtain a copy of the License at
REM
REM http://www.apache.org/licenses/LICENSE-2.0
REM
REM Unless required by applicable law or agreed to in writing, software
REM distributed under the License is distributed on an "AS IS" BASIS,
REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
REM See the License for the specific language governing permissions and
REM limitations under the License.
REM
:: Getting parameters
if ("%1") == ("") goto error0
if ("%2") == ("") goto error0
if ("%3") == ("") goto error0
set arch=%1
if ("%2") == ("debug") set postfix=_debug
set output_dir=%3
:: Check if necessary .dll's already exist in output directory
set dlls=tbb%postfix%.dll tbbmalloc%postfix%.dll
(for %%a in (%dlls%) do (
if not exist %output_dir%\%%a (
goto copy_libs
)
))
:: Necessary .dll's already exist; no need to do anything
exit /B 0
:copy_libs
:: Optional 4th parameter to set install root
if ("%4") NEQ ("") set TBBROOT=%4
:: Actually we can set install root by ourselves
if ("%TBBROOT%") == ("") set TBBROOT=%~d0%~p0..\..\
:: Getting vs folders in case vc_mt binaries are not provided
:: ordered from oldest to newest, so we end with newest available version
if ("%VS140COMNTOOLS%") NEQ ("") set vc_dir=vc14
:: To use Microsoft* Visual Studio* 2017 IDE, make sure the variable VS150COMNTOOLS is set in your IDE instance.
:: If it is not, try running Microsoft Visual Studio 2017 from Microsoft* Developer Command Prompt* for VS 2017.
:: For details, see https://developercommunity.visualstudio.com/content/problem/730/vs154-env-var-vs150comntools-missing-from-build-sy.html
if ("%VS150COMNTOOLS%") NEQ ("") set vc_dir=vc14
:: The same comment also applies to Microsoft Visual Studio 2019 and variable VS160COMNTOOLS
if ("%VS160COMNTOOLS%") NEQ ("") set vc_dir=vc14
:: Are we standalone/oss or inside compiler?
if exist "%TBBROOT%\bin\%arch%\%vc_dir%\tbb%postfix%.dll" set interim_path=bin\%arch%
if exist "%TBBROOT%\..\redist\%arch%\tbb\%vc_dir%\tbb%postfix%.dll" set interim_path=..\redist\%arch%\tbb
if ("%interim_path%") == ("") goto error1
:: Do we provide vc_mt binaries?
if exist "%TBBROOT%\%interim_path%\vc_mt\tbb%postfix%.dll" set vc_dir=vc_mt
if ("%vc_dir%") == ("") goto error2
:: We know everything we wanted and there are no errors
:: Copying binaries
copy "%TBBROOT%\%interim_path%\%vc_dir%\tbb%postfix%.dll" "%output_dir%"
copy "%TBBROOT%\%interim_path%\%vc_dir%\tbb%postfix%.pdb" "%output_dir%"
copy "%TBBROOT%\%interim_path%\%vc_dir%\tbbmalloc%postfix%.dll" "%output_dir%"
copy "%TBBROOT%\%interim_path%\%vc_dir%\tbbmalloc%postfix%.pdb" "%output_dir%"
if exist "%TBBROOT%\%interim_path%\%vc_dir%\tbb_preview%postfix%.dll" copy "%TBBROOT%\%interim_path%\%vc_dir%\tbb_preview%postfix%.dll" "%output_dir%"
if exist "%TBBROOT%\%interim_path%\%vc_dir%\tbb_preview%postfix%.pdb" copy "%TBBROOT%\%interim_path%\%vc_dir%\tbb_preview%postfix%.pdb" "%output_dir%"
goto end
:error0
echo number of parameters not correct
exit /B 1
:error1
echo Could not determine path to TBB libraries
exit /B 1
:error2
echo Could not determine Visual Studio version
exit /B 1
:end
exit /B 0

View File

@@ -0,0 +1,34 @@
# Copyright (c) 2005-2020 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.
# detect if a compiler can support C++11
# If CXX0XFLAGS already set, do not change it
ifneq (,$(findstring icc, $(CXX))$(findstring icpc, $(CXX))$(findstring clang++, $(CXX)))
# every supported icc or clang is OK
CXX0XFLAGS ?= -std=c++11
else
ifneq (,$(findstring g++, $(CXX))$(findstring gcc, $(CXX)))
ifneq (, $(strip $(shell $(CXX) -v 2>&1 | grep "clang-")))
# This is clang actually,
# every supported clang is OK
CXX0XFLAGS ?= -std=c++11
else
# support of lambda started GCC 4.5
ifneq (, $(strip $(shell g++ -dumpfullversion -dumpversion | egrep "^(4\.[5-9]|[5-9]|1[0-9])")))
CXX0XFLAGS ?= -std=c++11
endif
endif
endif
endif

View File

@@ -0,0 +1,86 @@
# Copyright (c) 2005-2020 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.
# The C++ compiler
#CXX=g++
# detecting MS Windows (for MinGW support)
ifeq ($(OS), Windows_NT)
RM = cmd /C del /Q /F
RD = cmd /C rmdir
UI = con
EXE = $(NAME)$(SUFFIX).exe
else
RM = rm -f
RD = rmdir -r
# detecting 64-bit platform
arch ?= $(shell uname -m)
# Possible values of interest: intel64 x86_64 amd64 ia64 ppc64 sparc sparc64
x64 ?= $(findstring 64,$(subst sparc,sparc64,$(arch)))
# see https://wiki.debian.org/Multiarch/Tuples
MULTIARCH = $(arch)
ifeq ($(arch),ia32)
MULTIARCH = i386
endif
ifeq ($(arch),intel64)
MULTIARCH = x86_64
endif
ifeq ($(arch),ppc32)
MULTIARCH = powerpc
endif
ifeq ($(arch),sparc)
MULTIARCH = sparc64
endif
MULTIARCHTUPLE ?= $(MULTIARCH)-linux-gnu
# detecting UI ("mac", "x" or "con")
ifeq ($(shell uname),Darwin)
UI ?= mac
else
UI ?= $(shell sh -c "[ -f /usr/X11R6/lib$(x64)/libX11.so -o -f /usr/lib$(x64)/libX11.so -o -f /usr/lib/$(MULTIARCHTUPLE)/libX11.so ] && echo x")
endif
ifeq ($(UI),x)
EXE = $(NAME)$(SUFFIX)
UI_CXXFLAGS += -I/usr/X11R6/include
LIBS += -lpthread -L/usr/X11R6/lib$(x64) -lX11
# detect if libXext can be found
ifeq ($(shell sh -c "[ -f /usr/X11R6/lib$(x64)/libXext.so -o -f /usr/lib$(x64)/libXext.so -o -f /usr/lib/$(MULTIARCHTUPLE)/libXext.so ] && echo 0"),0)
LIBS += -lXext
else # no libXext
UI_CXXFLAGS += -DX_NOSHMEM
endif # libXext
else # ! X
ifeq ($(UI),mac)
CXX_UI?=g++
LIBS += -framework OpenGL -framework Foundation -framework Cocoa
MACUISOURCES = ../../common/gui/xcode/tbbExample/OpenGLView.m ../../common/gui/xcode/tbbExample/main.m ../../common/gui/xcode/tbbExample/tbbAppDelegate.m
MACUIOBJS = OpenGLView.o main.o tbbAppDelegate.o
APPRES = $(NAME)$(SUFFIX).app/Contents/Resources
EXE = $(NAME)$(SUFFIX).app/Contents/MacOS/$(NAME)$(SUFFIX)
else # ! macOS*
EXE = $(NAME)$(SUFFIX)
ifeq (,$(strip $(UI)))
UI = con
$(warning Note: no graphics output capability detected, building for console output.)
endif
endif # macOS
endif # X
endif # Windows vs. other

View File

@@ -0,0 +1,70 @@
# Copyright (c) 2005-2020 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.
# Per-build Makefile rules (for recursive $(MAKE) calls from Makefile)
# Base compile/link options
MYCXXFLAGS = /nologo /EHsc /Zc:forScope /D WIN32 /D _MBCS /D _CRT_SECURE_NO_DEPRECATE /MP $(CXXFLAGS)
MYLFLAGS = /link /incremental:no /fixed:no $(LFLAGS)
CXXFLAGS_NDEBUG = /MD /O2 /Ot /Gy /D NDEBUG
CXXFLAGS_DEBUG = /MDd /Od /Zi /D _DEBUG
# Specify library directory for Direct X SDK
DDLIB_DIR=$(DXSDK_DIR)\lib\$(XARCH:AMD64=x64)
# Input and output files
#SOURCE = v
#RCNAME = specified externaly
#EXE = ^
# defaults on XARCH = x86
UISRC = ../../common/gui/$(UI)video.cpp
default:
build_echo:
-@echo Building$(DEBUG) $(EXE) with UI=$(UI) XARCH=$(XARCH)
build_one: build_echo build_$(UI)$(DEBUG)
build_con: $(SOURCE) $(UISRC) compiler_check
$(CXX) $(CXXFLAGS_NDEBUG) $(MYCXXFLAGS) $(SOURCE) $(UISRC) $(MYLFLAGS) /subsystem:console /OUT:$(EXE)
@cmd.exe /C del *.obj
build_con_debug: $(SOURCE) $(UISRC) compiler_check
$(CXX) $(CXXFLAGS_DEBUG) $(MYCXXFLAGS) $(SOURCE) $(UISRC) $(MYLFLAGS) /debug /subsystem:console /OUT:$(EXE)
@cmd.exe /C del *.obj
build_gdi: $(SOURCE) $(UISRC) msvs/$(RCNAME).res compiler_check
$(CXX) $(CXXFLAGS_NDEBUG) /D _WINDOWS $(MYCXXFLAGS) $(SOURCE) $(UISRC) $(MYLFLAGS) msvs/$(RCNAME).res /subsystem:windows /machine:$(XARCH) /OUT:$(EXE)
@cmd.exe /C del *.obj
build_gdi_debug: $(SOURCE) $(UISRC) msvs/$(RCNAME).res compiler_check
$(CXX) $(CXXFLAGS_DEBUG) /D _WINDOWS $(MYCXXFLAGS) $(SOURCE) $(UISRC) $(MYLFLAGS) msvs/$(RCNAME).res /debug /subsystem:windows /machine:$(XARCH) /OUT:$(EXE)
@cmd.exe /C del *.obj
build_d2d: $(SOURCE) $(UISRC) msvs/$(RCNAME).res compiler_check
-@echo Using DirectX SDK from "$(DDLIB_DIR)"
$(CXX) $(CXXFLAGS_NDEBUG) /D _WINDOWS $(MYCXXFLAGS) /I "$(DXSDK_DIR)\include" $(SOURCE) $(UISRC) $(MYLFLAGS) /LIBPATH:"$(DDLIB_DIR)" msvs/$(RCNAME).res /subsystem:windows /machine:$(XARCH) /OUT:$(EXE)
@cmd.exe /C del *.obj
build_d2d_debug: $(SOURCE) $(UISRC) msvs/$(RCNAME).res compiler_check
-@echo Using DirectX SDK from "$(DDLIB_DIR)"
$(CXX) $(CXXFLAGS_DEBUG) /D _WINDOWS $(MYCXXFLAGS) /I "$(DXSDK_DIR)\include" $(SOURCE) $(UISRC) $(MYLFLAGS) /LIBPATH:"$(DDLIB_DIR)" msvs/$(RCNAME).res /debug /subsystem:windows /machine:$(XARCH) /OUT:$(EXE)
@cmd.exe /C del *.obj
msvs/$(RCNAME).res:
rc /r msvs/$(RCNAME)
compiler_check:
@echo compiler_test>compiler_test && @$(CXX) /E compiler_test >nul 2>&1 || echo "$(CXX) command not found. Check if CXX=$(CXX) is set properly"
@cmd.exe /C del compiler_test

View File

@@ -0,0 +1,132 @@
/*
Copyright (c) 2005-2020 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 "video.h"
#include <cassert>
#include <stdio.h>
unsigned int * g_pImg = 0;
int g_sizex, g_sizey;
static video *g_video = 0;
static int g_fps = 0;
#if _WIN32 || _WIN64
static DWORD g_msec = 0;
#ifdef _WINDOWS
HINSTANCE video::win_hInstance = 0;
int video::win_iCmdShow = 0;
void video::win_set_class(WNDCLASSEX &wcex) { }
void video::win_load_accelerators(int idc) { }
#endif //_WINDOWS
#else
#include <sched.h>
#include <sys/time.h>
struct timeval g_time;
#endif //_WIN32||_WIN64
#define CALC_FPS_ENABLED ((WINAPI_FAMILY != WINAPI_FAMILY_APP) && (!__ANDROID__))
video::video()
// OpenGL* RGBA byte order for little-endian CPU
: depth(24), red_shift(0), green_shift(8), blue_shift(16),
red_mask(0xff), green_mask(0xff00), blue_mask(0xff0000)
{
assert(g_video == 0);
g_video = this; title = "Video"; updating = calc_fps = false;
}
bool video::init_window(int x, int y)
{
g_sizex = x; g_sizey = y;
g_pImg = new unsigned int[x*y];
running = true;
return false;
}
bool video::init_console()
{
running = true;
return true;
}
void video::terminate()
{
#if CALC_FPS_ENABLED
if(calc_fps) {
double fps = g_fps;
#if _WIN32 || _WIN64
fps /= (GetTickCount()-g_msec)/1000.0;
#else
struct timezone tz; struct timeval end_time; gettimeofday(&end_time, &tz);
fps /= (end_time.tv_sec+1.0*end_time.tv_usec/1000000.0) - (g_time.tv_sec+1.0*g_time.tv_usec/1000000.0);
#endif
printf("%s: %.1f fps\n", title, fps);
}
#endif
g_video = 0; running = false;
if(g_pImg) { delete[] g_pImg; g_pImg = 0; }
}
video::~video()
{
if(g_video) terminate();
}
//! Count and display FPS count in titlebar
bool video::next_frame()
{
#if CALC_FPS_ENABLED
if(calc_fps){
if(!g_fps) {
#if _WIN32 || _WIN64
g_msec = GetTickCount();
#else
struct timezone tz; gettimeofday(&g_time, &tz);
#endif
}
g_fps++;
}
#endif
return running;
}
//! Do standard loop
void video::main_loop()
{
on_process();
}
//! Change window title
void video::show_title()
{
}
///////////////////////////////////////////// public methods of video class ///////////////////////
drawing_area::drawing_area(int x, int y, int sizex, int sizey)
: base_index(y*g_sizex + x), max_index(g_sizex*g_sizey), index_stride(g_sizex),
pixel_depth(24), ptr32(g_pImg), start_x(x), start_y(y), size_x(sizex), size_y(sizey)
{
assert(x < g_sizex); assert(y < g_sizey);
assert(x+sizex <= g_sizex); assert(y+sizey <= g_sizey);
index = base_index; // current index
}
void drawing_area::update() {}

View File

@@ -0,0 +1,197 @@
/*
Copyright (c) 2005-2020 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.
*/
// common Windows parts
#include "winvideo.h"
// and another headers
#include <cassert>
#include <stdio.h>
#include <dxsdkver.h>
#if _DXSDK_PRODUCT_MAJOR < 9
#error DXSDK Version 9 and above required.
#endif
#include <d2d1.h>
#include <d2d1helper.h>
#pragma comment(lib, "d2d1.lib")
ID2D1Factory *m_pD2DFactory;
ID2D1HwndRenderTarget *m_pRenderTarget;
ID2D1Bitmap *m_pBitmap;
D2D1_SIZE_U bitmapSize;
HANDLE g_hVSync;
#include <DXErr.h>
#pragma comment(lib, "DxErr.lib")
//! Create a dialog box and tell the user what went wrong
bool DisplayError(LPSTR lpstrErr, HRESULT hres)
{
if(hres != S_OK){
static bool InError = false;
int retval = 0;
if (!InError)
{
InError = true;
const char *message = hres?DXGetErrorString(hres):0;
retval = MessageBoxA(g_hAppWnd, lpstrErr, hres?message:"Error!", MB_OK|MB_ICONERROR);
InError = false;
}
}
return false;
}
void DrawBitmap()
{
HRESULT hr = S_OK;
if (m_pRenderTarget) {
m_pRenderTarget->BeginDraw();
if (m_pBitmap)
hr = m_pBitmap->CopyFromMemory(NULL,(BYTE*)g_pImg, 4*g_sizex);
DisplayError( "DrawBitmap error", hr );
m_pRenderTarget->DrawBitmap(m_pBitmap);
m_pRenderTarget->EndDraw();
}
return;
}
inline void mouse(int k, LPARAM lParam)
{
int x = (int)LOWORD(lParam);
int y = (int)HIWORD(lParam);
RECT rc;
GetClientRect(g_hAppWnd, &rc);
g_video->on_mouse( x*g_sizex/(rc.right - rc.left), y*g_sizey/(rc.bottom - rc.top), k );
}
//! Win event processing function
LRESULT CALLBACK InternalWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch (iMsg)
{
case WM_MOVE:
// Check to make sure our window exists before we tell it to repaint.
// This will fail the first time (while the window is being created).
if (hwnd) {
InvalidateRect(hwnd, NULL, FALSE);
UpdateWindow(hwnd);
}
return 0L;
case WM_SIZE:
case WM_PAINT:
if( g_video->running && g_video->updating ) {
DrawBitmap();
Sleep(0);
}
break;
// Process all mouse and keyboard events
case WM_LBUTTONDOWN: mouse( 1, lParam ); break;
case WM_LBUTTONUP: mouse(-1, lParam ); break;
case WM_RBUTTONDOWN: mouse( 2, lParam ); break;
case WM_RBUTTONUP: mouse(-2, lParam ); break;
case WM_MBUTTONDOWN: mouse( 3, lParam ); break;
case WM_MBUTTONUP: mouse(-3, lParam ); break;
case WM_CHAR: g_video->on_key( (int)wParam); break;
// some useless stuff
case WM_ERASEBKGND: return 1; // keeps erase-background events from happening, reduces chop
case WM_DISPLAYCHANGE: return 0;
// Now, shut down the window...
case WM_DESTROY: PostQuitMessage(0); return 0;
}
// call user defined proc, if exists
return g_pUserProc? g_pUserProc(hwnd, iMsg, wParam, lParam) : DefWindowProc(hwnd, iMsg, wParam, lParam);
}
bool video::init_window(int sizex, int sizey)
{
assert(win_hInstance != 0);
g_sizex = sizex; g_sizey = sizey;
if (!WinInit(win_hInstance, win_iCmdShow, gWndClass, title, false)) {
DisplayError("Unable to initialize the program's window.");
return false;
}
ShowWindow(g_hAppWnd, SW_SHOW);
g_pImg = new unsigned int[sizex*sizey];
HRESULT hr = S_OK;
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2DFactory);
// Create a Direct2D render target.
if (SUCCEEDED(hr) && !m_pRenderTarget){
RECT rc;
GetClientRect(g_hAppWnd, &rc);
bitmapSize = D2D1::SizeU(
rc.right - rc.left,
rc.bottom - rc.top
);
hr = m_pD2DFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(g_hAppWnd, bitmapSize),
&m_pRenderTarget
);
if (SUCCEEDED(hr) && !m_pBitmap){
D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat(
DXGI_FORMAT_B8G8R8A8_UNORM,
D2D1_ALPHA_MODE_IGNORE
);
D2D1_BITMAP_PROPERTIES bitmapProperties;
bitmapProperties.pixelFormat = pixelFormat;
m_pRenderTarget->GetDpi( &bitmapProperties.dpiX, &bitmapProperties.dpiY );
m_pRenderTarget->CreateBitmap(bitmapSize,bitmapProperties,&m_pBitmap);
m_pRenderTarget->DrawBitmap(m_pBitmap);
}
}
running = true;
return true;
}
void video::terminate()
{
if (m_pBitmap) m_pBitmap->Release();
if (m_pRenderTarget) m_pRenderTarget->Release();
if (m_pD2DFactory) m_pD2DFactory->Release();
g_video = 0; running = false;
if(g_pImg) { delete[] g_pImg; g_pImg = 0; }
}
//////////// drawing area constructor & destructor /////////////
drawing_area::drawing_area(int x, int y, int sizex, int sizey)
: base_index(y*g_sizex + x), max_index(g_sizex*g_sizey), index_stride(g_sizex),
pixel_depth(24), ptr32(g_pImg), start_x(x), start_y(y), size_x(sizex), size_y(sizey)
{
assert(x < g_sizex); assert(y < g_sizey);
assert(x+sizex <= g_sizex); assert(y+sizey <= g_sizey);
index = base_index; // current index
}
void drawing_area::update()
{
if(g_video->updating) {
RECT r;
r.left = start_x; r.right = start_x + size_x;
r.top = start_y; r.bottom = start_y + size_y;
InvalidateRect(g_hAppWnd, &r, false);
}
}

View File

@@ -0,0 +1,24 @@
@echo off
REM
REM Copyright (c) 2005-2020 Intel Corporation
REM
REM Licensed under the Apache License, Version 2.0 (the "License");
REM you may not use this file except in compliance with the License.
REM You may obtain a copy of the License at
REM
REM http://www.apache.org/licenses/LICENSE-2.0
REM
REM Unless required by applicable law or agreed to in writing, software
REM distributed under the License is distributed on an "AS IS" BASIS,
REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
REM See the License for the specific language governing permissions and
REM limitations under the License.
REM
if "%DXSDK_DIR%"=="" goto error_no_DXSDK
goto end
:error_no_DXSDK
echo DirectX SDK Check : error : This example requires the DirectX SDK. Either (re)-install the DirectX SDK, or set the DXSDK_DIR environment variable to indicate where it is installed.
:end

View File

@@ -0,0 +1,142 @@
/*
Copyright (c) 2005-2020 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.
*/
// common Windows parts
#include "winvideo.h"
// include GDI+ headers
#include <gdiplus.h>
// and another headers
#include <stdio.h>
// tag linking library
#pragma comment(lib, "gdiplus.lib")
// global specific variables
Gdiplus::Bitmap * g_pBitmap; // main drawing bitmap
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartupInput gdiplusStartupInput;// GDI+
//! display system error
bool DisplayError(LPSTR lpstrErr, HRESULT hres)
{
static bool InError = false;
int retval = 0;
if (!InError)
{
InError = true;
LPCSTR lpMsgBuf;
if(!hres) hres = GetLastError();
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, hres, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL );
retval = MessageBox(g_hAppWnd, lpstrErr, lpMsgBuf, MB_OK|MB_ICONERROR);
LocalFree( (HLOCAL)lpMsgBuf );
InError = false;
}
return false;
}
//! Win event processing function
LRESULT CALLBACK InternalWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch (iMsg)
{
case WM_MOVE:
// Check to make sure our window exists before we tell it to repaint.
// This will fail the first time (while the window is being created).
if (hwnd) {
InvalidateRect(hwnd, NULL, FALSE);
UpdateWindow(hwnd);
}
return 0L;
case WM_PAINT:
{
PAINTSTRUCT ps;
Gdiplus::Graphics graphics( BeginPaint(hwnd, &ps) );
// redraw just requested area. This call is as fast as simple DrawImage() call.
if(g_video->updating) graphics.DrawImage(g_pBitmap, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.left, ps.rcPaint.top,
ps.rcPaint.right, ps.rcPaint.bottom, Gdiplus::UnitPixel);
EndPaint(hwnd, &ps);
}
return 0L;
// Process all mouse and keyboard events
case WM_LBUTTONDOWN: g_video->on_mouse( (int)LOWORD(lParam), (int)HIWORD(lParam), 1); break;
case WM_LBUTTONUP: g_video->on_mouse( (int)LOWORD(lParam), (int)HIWORD(lParam), -1); break;
case WM_RBUTTONDOWN: g_video->on_mouse( (int)LOWORD(lParam), (int)HIWORD(lParam), 2); break;
case WM_RBUTTONUP: g_video->on_mouse( (int)LOWORD(lParam), (int)HIWORD(lParam), -2); break;
case WM_MBUTTONDOWN: g_video->on_mouse( (int)LOWORD(lParam), (int)HIWORD(lParam), 3); break;
case WM_MBUTTONUP: g_video->on_mouse( (int)LOWORD(lParam), (int)HIWORD(lParam), -3); break;
case WM_CHAR: g_video->on_key( (int)wParam); break;
// some useless stuff
case WM_ERASEBKGND: return 1; // keeps erase-background events from happening, reduces chop
case WM_DISPLAYCHANGE: return 0;
// Now, shut down the window...
case WM_DESTROY: PostQuitMessage(0); return 0;
}
// call user defined proc, if exists
return g_pUserProc? g_pUserProc(hwnd, iMsg, wParam, lParam) : DefWindowProc(hwnd, iMsg, wParam, lParam);
}
///////////// video functions ////////////////
bool video::init_window(int sizex, int sizey)
{
assert(win_hInstance != 0);
g_sizex = sizex; g_sizey = sizey;
if (!WinInit(win_hInstance, win_iCmdShow, gWndClass, title, true)) {
DisplayError("Unable to initialize the program's window.");
return false;
}
ShowWindow(g_hAppWnd, SW_SHOW);
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
g_pImg = new unsigned int[sizex*sizey];
g_pBitmap = new Gdiplus::Bitmap(g_sizex, g_sizey, 4*g_sizex, PixelFormat32bppRGB, (BYTE*)g_pImg );
running = true;
return true;
}
void video::terminate()
{
if(g_pBitmap) { delete g_pBitmap; g_pBitmap = 0; }
Gdiplus::GdiplusShutdown(gdiplusToken);
g_video = 0; running = false;
if(g_pImg) { delete[] g_pImg; g_pImg = 0; }
}
//////////// drawing area constructor & destructor /////////////
drawing_area::drawing_area(int x, int y, int sizex, int sizey)
: base_index(y*g_sizex + x), max_index(g_sizex*g_sizey), index_stride(g_sizex),
pixel_depth(24), ptr32(g_pImg), start_x(x), start_y(y), size_x(sizex), size_y(sizey)
{
assert(x < g_sizex); assert(y < g_sizey);
assert(x+sizex <= g_sizex); assert(y+sizey <= g_sizey);
index = base_index; // current index
}
void drawing_area::update()
{
if(g_video->updating) {
RECT r;
r.left = start_x; r.right = start_x + size_x;
r.top = start_y; r.bottom = start_y + size_y;
InvalidateRect(g_hAppWnd, &r, false);
}
}

View File

@@ -0,0 +1,160 @@
/*
Copyright (c) 2005-2020 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 "video.h"
#include <cassert>
#include <stdio.h>
#include <iostream>
#include <pthread.h>
unsigned int* g_pImg = 0;
int g_sizex=0, g_sizey=0;
static video *g_video = 0;
static int g_fps = 0;
char *window_title=NULL;
#define WINDOW_TITLE_SIZE 256
int cocoa_update=0;
#include <sched.h>
#include <sys/time.h>
struct timeval g_time;
video::video()
#if __TBB_IOS
: depth(24), red_shift(0), green_shift(8), blue_shift(16),
red_mask(0xff), green_mask(0xff00), blue_mask(0xff0000)
#else
: depth(24), red_shift(16), green_shift(8), blue_shift(0),
red_mask(0xff0000), green_mask(0xff00), blue_mask(0xff)
#endif
{
assert(g_video == 0);
g_video = this; title = "Video"; cocoa_update=1; updating = true; calc_fps = false;
}
bool video::init_window(int x, int y)
{
g_sizex = x; g_sizey = y;
g_pImg = new unsigned int[x*y];
if( window_title==NULL )
window_title = (char*)malloc(WINDOW_TITLE_SIZE);
strncpy( window_title, title, WINDOW_TITLE_SIZE-1 );
running = true;
return true;
}
bool video::init_console()
{
running = true;
return true;
}
void video::terminate()
{
if(calc_fps) {
double fps = g_fps;
struct timezone tz; struct timeval end_time; gettimeofday(&end_time, &tz);
fps /= (end_time.tv_sec+1.0*end_time.tv_usec/1000000.0) - (g_time.tv_sec+1.0*g_time.tv_usec/1000000.0);
printf("%s: %.1f fps\n", title, fps);
}
g_video = 0; running = false;
if(g_pImg) { delete[] g_pImg; g_pImg = 0; }
}
video::~video()
{
if(g_video) terminate();
}
//! Count and display FPS count in titlebar
bool video::next_frame()
{
if(calc_fps){
if(!g_fps) {
struct timezone tz; gettimeofday(&g_time, &tz);
}
g_fps++;
}
struct timezone tz; struct timeval now_time; gettimeofday(&now_time, &tz);
double sec=((now_time.tv_sec+1.0*now_time.tv_usec/1000000.0) - (g_time.tv_sec+1.0*g_time.tv_usec/1000000.0));
if( sec>1 ){
if(calc_fps) {
memcpy(&g_time, &now_time, sizeof(g_time));
int fps;
fps = g_fps/sec;
cocoa_update = (int)updating;
snprintf(window_title,WINDOW_TITLE_SIZE, "%s%s: %d fps", title, updating?"":" (no updating)", int(fps));
g_fps=0;
}
}
return running;
}
void* thread_func(void*)
{
g_video->on_process();
exit(EXIT_SUCCESS);
}
extern "C" void on_mouse_func(int x, int y, int k)
{
g_video->on_mouse(x, y, k);
return;
}
extern "C" void on_key_func(int x)
{
g_video->on_key(x);
return;
}
extern "C" int cocoa_main( int argc, char *argv[] );
//! Do standard loop
void video::main_loop()
{
pthread_t handle;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&handle,&attr,&thread_func,(void*)NULL);
pthread_detach(handle);
cocoa_main( 0, NULL );
}
//! Change window title
void video::show_title()
{
if(title)
strncpy( window_title, title, WINDOW_TITLE_SIZE );
return;
}
///////////////////////////////////////////// public methods of video class ///////////////////////
drawing_area::drawing_area(int x, int y, int sizex, int sizey)
: base_index(y*g_sizex + x), max_index(g_sizex*g_sizey), index_stride(g_sizex),
pixel_depth(24), ptr32(g_pImg), start_x(x), start_y(y), size_x(sizex), size_y(sizey)
{
assert(x < g_sizex); assert(y < g_sizey);
assert(x+sizex <= g_sizex); assert(y+sizey <= g_sizey);
index = base_index; // current index
}
void drawing_area::update()
{
//nothing to do, updating via timer in cocoa part.
}

View File

@@ -0,0 +1,237 @@
/*
Copyright (c) 2005-2020 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.
*/
#ifndef __VIDEO_H__
#define __VIDEO_H__
#include <cassert>
#if _MSC_VER
#include <stddef.h> // for uintptr_t
#else
#include <stdint.h> // for uintptr_t
#endif
#if _WIN32 || _WIN64
#include <windows.h>
#else
#include <unistd.h>
#endif
typedef unsigned int color_t;
typedef unsigned char colorcomp_t;
typedef signed char depth_t;
//! Class for getting access to drawing memory
class drawing_memory
{
#ifdef __TBB_MIC_OFFLOAD
// The address is kept as uintptr_t since
// the compiler could not offload a pointer
#endif
uintptr_t my_address;
public:
depth_t pixel_depth;
int sizex, sizey;
//! Get drawing memory
inline char* get_address() const { return reinterpret_cast<char*>(my_address); }
//! Get drawing memory size
inline int get_size() const { return ((pixel_depth>16) ? 4:2) * sizex * sizey; }
//! Set drawing memory
inline void set_address(char *mem) { my_address = reinterpret_cast<uintptr_t>(mem); }
friend class drawing_area;
friend class video;
};
//! Simple proxy class for managing of different video systems
class video
{
//! colorspace information
depth_t depth, red_shift, green_shift, blue_shift;
color_t red_mask, green_mask, blue_mask;
friend class drawing_area;
public:
//! Constructor
video();
//! Destructor
~video();
//! member to set window name
const char *title;
//! true is enable to show fps
bool calc_fps;
//! if true: on windows fork processing thread for on_process(), on non-windows note that next_frame() is called concurrently.
bool threaded;
//! true while running within main_loop()
bool running;
//! if true, do gui updating
bool updating;
//! initialize graphical video system
bool init_window(int sizex, int sizey);
//! initialize console. returns true if console is available
bool init_console();
//! terminate video system
void terminate();
//! Do standard event & processing loop. Use threaded = true to separate event/updating loop from frame processing
void main_loop();
//! Process next frame
bool next_frame();
//! Change window title
void show_title();
//! translate RGB components into packed type
inline color_t get_color(colorcomp_t red, colorcomp_t green, colorcomp_t blue) const;
//! Get drawing memory descriptor
inline drawing_memory get_drawing_memory() const;
//! code of the ESCape key
static const int esc_key = 27;
//! Mouse events handler.
virtual void on_mouse(int x, int y, int key) { }
//! Mouse events handler.
virtual void on_key(int key) { }
//! Main processing loop. Redefine with your own
virtual void on_process() { while(next_frame()); }
#ifdef _WINDOWS
//! Windows specific members
//! if VIDEO_WINMAIN isn't defined then set this just before init() by arguments of WinMain
static HINSTANCE win_hInstance; static int win_iCmdShow;
//! optionally call it just before init() to set own. Use ascii strings convention
void win_set_class(WNDCLASSEX &);
//! load and set accelerator table from resources
void win_load_accelerators(int idc);
#endif
};
//! Drawing class
class drawing_area
{
const size_t base_index, max_index, index_stride;
const depth_t pixel_depth;
unsigned int * const ptr32;
size_t index;
public:
const int start_x, start_y, size_x, size_y;
//! constructors
drawing_area(int x, int y, int sizex, int sizey);
inline drawing_area(int x, int y, int sizex, int sizey, const drawing_memory &dmem);
//! destructor
inline ~drawing_area();
//! update the image
void update();
//! set current position. local_x could be bigger then size_x
inline void set_pos(int local_x, int local_y);
//! put pixel in current position with incremental address calculating to next right pixel
inline void put_pixel(color_t color);
//! draw pixel at position by packed color
void set_pixel(int localx, int localy, color_t color)
{ set_pos(localx, localy); put_pixel(color); }
};
extern int g_sizex;
extern int g_sizey;
extern unsigned int *g_pImg;
inline drawing_memory video::get_drawing_memory() const
{
drawing_memory dmem;
dmem.pixel_depth = depth;
dmem.my_address = reinterpret_cast<uintptr_t>(g_pImg);
dmem.sizex = g_sizex;
dmem.sizey = g_sizey;
return dmem;
}
inline color_t video::get_color(colorcomp_t red, colorcomp_t green, colorcomp_t blue) const
{
if(red_shift == 16) // only for depth == 24 && red_shift > blue_shift
return (red<<16) | (green<<8) | blue;
else if(depth >= 24)
return
#if __ANDROID__
// Setting Alpha to 0xFF
0xFF000000 |
#endif
(red<<red_shift) | (green<<green_shift) | (blue<<blue_shift);
else if(depth > 0) {
depth_t bs = blue_shift, rs = red_shift;
if(blue_shift < 0) blue >>= -bs, bs = 0;
else /*red_shift < 0*/ red >>= -rs, rs = 0;
return ((red<<rs)&red_mask) | ((green<<green_shift)&green_mask) | ((blue<<bs)&blue_mask);
} else { // UYVY colorspace
unsigned y, u, v;
y = red * 77 + green * 150 + blue * 29; // sum(77+150+29=256) * max(=255): limit->2^16
u = (2048 + (blue << 3) - (y >> 5)) >> 4; // (limit->2^12)>>4
v = (2048 + (red << 3) - (y >> 5)) >> 4;
y = y >> 8;
return u | (y << 8) | (v << 16) | (y << 24);
}
}
inline drawing_area::drawing_area(int x, int y, int sizex, int sizey, const drawing_memory &dmem)
: base_index(y*dmem.sizex + x), max_index(dmem.sizex*dmem.sizey), index_stride(dmem.sizex),
pixel_depth(dmem.pixel_depth), ptr32(reinterpret_cast<unsigned int*>(dmem.my_address)),
start_x(x), start_y(y), size_x(sizex), size_y(sizey)
{
assert(x < dmem.sizex); assert(y < dmem.sizey);
assert(x+sizex <= dmem.sizex); assert(y+sizey <= dmem.sizey);
index = base_index; // current index
}
inline void drawing_area::set_pos(int local_x, int local_y)
{
index = base_index + local_x + local_y*index_stride;
}
inline void drawing_area::put_pixel(color_t color)
{
assert(index < max_index);
if(pixel_depth > 16) ptr32[index++] = color;
else if(pixel_depth > 0)
((unsigned short*)ptr32)[index++] = (unsigned short)color;
else { // UYVY colorspace
if(index&1) color >>= 16;
((unsigned short*)ptr32)[index++] = (unsigned short)color;
}
}
inline drawing_area::~drawing_area()
{
#if ! __TBB_DEFINE_MIC
update();
#endif
}
#if defined(_WINDOWS) && (defined(VIDEO_WINMAIN) || defined(VIDEO_WINMAIN_ARGS) )
#include <cstdlib>
//! define WinMain for subsystem:windows.
#ifdef VIDEO_WINMAIN_ARGS
int main(int, char *[]);
#else
int main();
#endif
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR szCmdLine, int iCmdShow)
{
video::win_hInstance = hInstance; video::win_iCmdShow = iCmdShow;
#ifdef VIDEO_WINMAIN_ARGS
return main(__argc, __argv);
#else
return main();
#endif
}
#endif
#endif// __VIDEO_H__

View File

@@ -0,0 +1,279 @@
/*
Copyright (c) 2005-2020 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.
*/
/////// Common internal implementation of Windows-specific stuff //////////////
/////// Must be the first included header //////////////
#ifndef __WINVIDEO_H__
#define __WINVIDEO_H__
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
#endif
// Check that the target Windows version has all API calls required.
#ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0400
#endif
#if _WIN32_WINNT<0x0400
# define YIELD_TO_THREAD() Sleep(0)
#else
# define YIELD_TO_THREAD() SwitchToThread()
#endif
#include "video.h"
#include <fcntl.h>
#include <io.h>
#include <iostream>
#include <fstream>
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "user32.lib")
// maximum number of lines the output console should have
static const WORD MAX_CONSOLE_LINES = 500;
const COLORREF RGBKEY = RGB(8, 8, 16); // at least 8 for 16-bit palette
HWND g_hAppWnd; // The program's window handle
HANDLE g_handles[2] = {0,0};// thread and wake up event
unsigned int * g_pImg = 0; // drawing memory
int g_sizex, g_sizey;
static video * g_video = 0;
WNDPROC g_pUserProc = 0;
HINSTANCE video::win_hInstance = 0;
int video::win_iCmdShow = 0;
static WNDCLASSEX * gWndClass = 0;
static HACCEL hAccelTable = 0;
static DWORD g_msec = 0;
static int g_fps = 0, g_updates = 0, g_skips = 0;
bool DisplayError(LPSTR lpstrErr, HRESULT hres = 0); // always returns false
LRESULT CALLBACK InternalWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
//! Create window
bool WinInit(HINSTANCE hInstance, int nCmdShow, WNDCLASSEX *uwc, const char *title, bool fixedsize)
{
WNDCLASSEX wndclass; // Our app's windows class
if(uwc) {
memcpy(&wndclass, uwc, sizeof(wndclass));
g_pUserProc = uwc->lpfnWndProc;
} else {
memset(&wndclass, 0, sizeof(wndclass));
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.lpszClassName = title;
}
wndclass.cbSize = sizeof(wndclass);
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = InternalWndProc;
wndclass.style |= CS_HREDRAW | CS_VREDRAW;
wndclass.hbrBackground = CreateSolidBrush(RGBKEY);
if( !RegisterClassExA(&wndclass) ) return false;
int xaddend = GetSystemMetrics(fixedsize?SM_CXFIXEDFRAME:SM_CXFRAME)*2;
int yaddend = GetSystemMetrics(fixedsize?SM_CYFIXEDFRAME:SM_CYFRAME)*2 + GetSystemMetrics(SM_CYCAPTION);
if(wndclass.lpszMenuName) yaddend += GetSystemMetrics(SM_CYMENU);
// Setup the new window's physical parameters - and tell Windows to create it
g_hAppWnd = CreateWindowA(wndclass.lpszClassName, // Window class name
title, // Window caption
!fixedsize ? WS_OVERLAPPEDWINDOW : // Window style
WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,
CW_USEDEFAULT, // Initial x pos: use default placement
0, // Initial y pos: not used here
g_sizex+xaddend,// Initial x size
g_sizey+yaddend,// Initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // Creation parameters
return g_hAppWnd != NULL;
}
//! create console window with redirection
static bool RedirectIOToConsole(void)
{
int hConHandle; size_t lStdHandle;
CONSOLE_SCREEN_BUFFER_INFO coninfo;
FILE *fp;
// allocate a console for this app
AllocConsole();
// set the screen buffer to be big enough to let us scroll text
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
coninfo.dwSize.Y = MAX_CONSOLE_LINES;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
// redirect unbuffered STDOUT to the console
lStdHandle = (size_t)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
if(hConHandle <= 0) return false;
fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
// redirect unbuffered STDERR to the console
lStdHandle = (size_t)GetStdHandle(STD_ERROR_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
if(hConHandle > 0) {
fp = _fdopen( hConHandle, "w" );
*stderr = *fp;
setvbuf( stderr, NULL, _IONBF, 0 );
}
// redirect unbuffered STDIN to the console
lStdHandle = (size_t)GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
if(hConHandle > 0) {
fp = _fdopen( hConHandle, "r" );
*stdin = *fp;
setvbuf( stdin, NULL, _IONBF, 0 );
}
// make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
// point to console as well
std::ios::sync_with_stdio();
return true;
}
video::video()
: depth(24), red_shift(16), green_shift(8), blue_shift(0),
red_mask(0xff0000), green_mask(0xff00), blue_mask(0xff)
{
assert(g_video == 0);
g_video = this; title = "Video"; running = threaded = calc_fps = false; updating = true;
}
//! optionally call it just before init() to set own
void video::win_set_class(WNDCLASSEX &wcex)
{
gWndClass = &wcex;
}
void video::win_load_accelerators(int idc)
{
hAccelTable = LoadAccelerators(win_hInstance, MAKEINTRESOURCE(idc));
}
bool video::init_console()
{
if(RedirectIOToConsole()) {
if(!g_pImg && g_sizex && g_sizey)
g_pImg = new unsigned int[g_sizex * g_sizey];
if(g_pImg) running = true;
return true;
}
return false;
}
video::~video()
{
if(g_video) terminate();
}
DWORD WINAPI thread_video(LPVOID lpParameter)
{
video *v = (video*)lpParameter;
v->on_process();
return 0;
}
static bool loop_once(video *v)
{
// screen update notify
if(int updates = g_updates) {
g_updates = 0;
if(g_video->updating) { g_skips += updates-1; g_fps++; }
else g_skips += updates;
UpdateWindow(g_hAppWnd);
}
// update fps
DWORD msec = GetTickCount();
if(v->calc_fps && msec >= g_msec+1000) {
double sec = (msec - g_msec)/1000.0;
char buffer[256], n = _snprintf(buffer, 128, "%s: %d fps", v->title, int(double(g_fps + g_skips)/sec));
if(g_skips) _snprintf(buffer+n, 128, " - %d skipped = %d updates", int(g_skips/sec), int(g_fps/sec));
SetWindowTextA(g_hAppWnd, buffer);
g_msec = msec; g_skips = g_fps = 0;
}
// event processing, including painting
MSG msg;
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
if( msg.message == WM_QUIT ) { v->running = false; return false; }
if( !hAccelTable || !TranslateAccelerator(msg.hwnd, hAccelTable, &msg) ){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return true; // try again
}
return false;
}
//! Do standard event loop
void video::main_loop()
{
// let Windows draw and unroll the window
InvalidateRect(g_hAppWnd, 0, false);
g_msec = GetTickCount(); // let's stay for 0,5 sec
while(g_msec + 500 > GetTickCount()) { loop_once(this); Sleep(1); }
g_msec = GetTickCount();
// now, start main process
if(threaded) {
g_handles[0] = CreateThread (
NULL, // LPSECURITY_ATTRIBUTES security_attrs
0, // SIZE_T stacksize
(LPTHREAD_START_ROUTINE) thread_video,
this, // argument
0, 0);
if(!g_handles[0]) { DisplayError("Can't create thread"); return; }
else // harmless race is possible here
g_handles[1] = CreateEvent(NULL, false, false, NULL);
while(running) {
while(loop_once(this));
YIELD_TO_THREAD(); // give time for processing when running on single CPU
DWORD r = MsgWaitForMultipleObjects(2, g_handles, false, INFINITE, QS_ALLINPUT^QS_MOUSEMOVE);
if(r == WAIT_OBJECT_0) break; // thread terminated
}
running = false;
if(WaitForSingleObject(g_handles[0], 3000) == WAIT_TIMEOUT){
// there was not enough time for graceful shutdown, killing the example with code 1.
exit(1);
}
if(g_handles[0]) CloseHandle(g_handles[0]);
if(g_handles[1]) CloseHandle(g_handles[1]);
g_handles[0] = g_handles[1] = 0;
}
else on_process();
}
//! Refresh screen picture
bool video::next_frame()
{
if(!running) return false;
g_updates++; // Fast but inaccurate counter. The data race here is benign.
if(!threaded) while(loop_once(this));
else if(g_handles[1]) {
SetEvent(g_handles[1]);
YIELD_TO_THREAD();
}
return true;
}
//! Change window title
void video::show_title()
{
if(g_hAppWnd)
SetWindowTextA(g_hAppWnd, title);
}
#endif //__WINVIDEO_H__

View File

@@ -0,0 +1,56 @@
/*
Copyright (c) 2005-2020 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.
*/
#import <Foundation/Foundation.h>
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
#import "OpenGLES/ES2/gl.h"
@interface OpenGLView : UIView {
NSTimer *timer;
CGRect imageRect;
}
@property (nonatomic, retain) NSTimer *timer;
@property (nonatomic) CGRect imageRect;
- (void) drawRect:(CGRect)rect;
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
@end
#elif TARGET_OS_MAC
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
@interface OpenGLView : NSOpenGLView{
NSTimer *timer;
}
@property (nonatomic,retain) NSTimer *timer;
- (void) drawRect:(NSRect)start;
- (void) mouseDown:(NSEvent *)theEvent;
- (void) keyDown:(NSEvent *)theEvent;
- (BOOL) acceptsFirstResponder;
- (void) viewDidEndLiveResize;
@end
#endif

View File

@@ -0,0 +1,143 @@
/*
Copyright (c) 2005-2020 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.
*/
#import <Foundation/Foundation.h>
#import "OpenGLView.h"
// defined in macvideo.cpp
extern char* window_title;
extern int cocoa_update;
extern int g_sizex, g_sizey;
extern unsigned int *g_pImg;
void on_mouse_func(int x, int y, int k);
void on_key_func(int x);
bool initialized = false;
#if TARGET_OS_IPHONE
#import "OpenGLES/ES2/gl.h"
@implementation OpenGLView
@synthesize timer;
@synthesize imageRect;
- (void)drawRect:(CGRect)start
{
if (initialized == false) {
NSLog(@"INITIALIZE");
timer = [NSTimer scheduledTimerWithTimeInterval:0.03 target:self selector:@selector(update_window) userInfo:nil repeats:YES];
imageRect = [[UIScreen mainScreen] bounds];
CGFloat full_height = imageRect.size.height;
const float ratio=(float)g_sizex/g_sizey;
imageRect.size.height=imageRect.size.width/ratio;
imageRect.origin.y=(full_height-imageRect.size.height)/2;
initialized = true;
}
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, g_pImg, 4*g_sizex*g_sizey, NULL);
CGImageRef inputImage = CGImageCreate(g_sizex, g_sizey, 8, 32, g_sizex * 4, colourSpace,(CGBitmapInfo)kCGImageAlphaNoneSkipLast, dataProvider, NULL, NO, kCGRenderingIntentDefault);
UIImage *image = [UIImage imageWithCGImage:inputImage];
CGDataProviderRelease(dataProvider);
CGColorSpaceRelease(colourSpace);
CGImageRelease(inputImage);
[image drawInRect:imageRect];
}
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint point = [[touches anyObject] locationInView:self];
const int x = point.x;
const int y = point.y;
if ( (y-imageRect.origin.y) > 0 && y < (imageRect.origin.y + imageRect.size.height ))
on_mouse_func( x*g_sizex/(imageRect.size.width), (y-imageRect.origin.y)*g_sizey/imageRect.size.height,1);
[self setNeedsDisplay];
}
-(void) update_window{
if( cocoa_update ) [self setNeedsDisplay];
}
@end
#elif TARGET_OS_MAC
#import <OpenGL/gl.h>
@implementation OpenGLView
@synthesize timer;
- (void) drawRect:(NSRect)start
{
if (initialized == false) {
NSLog(@"INITIALIZE");
timer = [NSTimer scheduledTimerWithTimeInterval:0.03 target:self selector:@selector(update_window) userInfo:nil repeats:YES];
initialized = true;
}
glWindowPos2i(0, (int)self.visibleRect.size.height);
glPixelZoom( (float)self.visibleRect.size.width /(float)g_sizex,
-(float)self.visibleRect.size.height/(float)g_sizey);
glDrawPixels(g_sizex, g_sizey, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, g_pImg);
glFlush();
}
-(void) update_window{
if( cocoa_update ) [self setNeedsDisplay:YES];
if( window_title ) [self.window setTitle:[NSString stringWithFormat:@"%s", window_title]];
}
-(void) keyDown:(NSEvent *)theEvent{
on_key_func([theEvent.characters characterAtIndex:0]);
}
-(void) mouseDown:(NSEvent *)theEvent{
// mouse event for seismic and fractal
NSPoint point= theEvent.locationInWindow;
const int x = (int)point.x;
const int y = (int)point.y;
NSRect rect = self.visibleRect;
on_mouse_func(x*g_sizex/(int)rect.size.width,((int)rect.size.height-y)*g_sizey/(int)rect.size.height,1);
[self setNeedsDisplay:YES];
}
- (BOOL) acceptsFirstResponder
{
return YES;
}
- (void) rightMouseDown:(NSEvent *)theEvent
{
return;
}
-(void) viewDidEndLiveResize
{
NSRect rect = self.visibleRect;
const int x=(int)rect.size.width;
const int y=(int)rect.size.height;
[self.window setTitle:[NSString stringWithFormat:@"X=%d Y=%d", x,y]];
}
@end
#endif

View File

@@ -0,0 +1 @@
APPL????

View File

@@ -0,0 +1,2 @@
/* Localized versions of Info.plist keys */

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9060"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
<connections>
<outlet property="delegate" destination="494" id="495"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application"/>
<menu title="AMainMenu" systemMenu="main" id="29">
<items>
<menuItem title="tbbExample" id="56">
<menu key="submenu" title="tbbExample" systemMenu="apple" id="57">
<items>
<menuItem title="Quit tbbExample" keyEquivalent="q" id="136">
<connections>
<action selector="terminate:" target="-3" id="449"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<window title="tbbExample" allowsToolTipsWhenApplicationIsInactive="NO" deferred="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" animationBehavior="default" id="371">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="100" y="100" width="480" height="360"/>
<rect key="screenRect" x="0.0" y="0.0" width="1280" height="1002"/>
<view key="contentView" focusRingType="none" horizontalHuggingPriority="1" verticalHuggingPriority="9" horizontalCompressionResistancePriority="1" verticalCompressionResistancePriority="1" id="372" customClass="OpenGLView">
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
<autoresizingMask key="autoresizingMask"/>
<animations/>
</view>
</window>
<customObject id="494" customClass="tbbAppDelegate">
<connections>
<outlet property="window" destination="371" id="532"/>
</connections>
</customObject>
<customObject id="420" customClass="NSFontManager"/>
</objects>
</document>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="AKo-RD-jUr">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="aF8-QV-POo">
<objects>
<viewController id="AKo-RD-jUr" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="SEe-ff-xUc"/>
<viewControllerLayoutGuide type="bottom" id="Cp9-IV-SKb"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="1aY-my-944" customClass="OpenGLView">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<animations/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="wcZ-9q-FxX" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="90" y="88"/>
</scene>
</scenes>
</document>

View File

@@ -0,0 +1,47 @@
/*
Copyright (c) 2005-2020 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.
*/
#import <Availability.h>
#import <Foundation/Foundation.h>
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
#import "tbbAppDelegate.h"
void get_screen_resolution(int *x, int *y) {
// Getting landscape screen resolution in any case
CGRect imageRect = [[UIScreen mainScreen] bounds];
*x=imageRect.size.width>imageRect.size.height?imageRect.size.width:imageRect.size.height;
*y=imageRect.size.width<imageRect.size.height?imageRect.size.width:imageRect.size.height;
return;
}
int cocoa_main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([tbbAppDelegate class]));
}
}
#elif TARGET_OS_MAC
#import <Cocoa/Cocoa.h>
int cocoa_main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **)argv);
}
#endif

View File

@@ -0,0 +1,47 @@
/*
Copyright (c) 2005-2020 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.
*/
//
// Created by Xcode* 4.3.2
//
#import <Foundation/Foundation.h>
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
@interface tbbAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
#elif TARGET_OS_MAC
#import <Cocoa/Cocoa.h>
@interface tbbAppDelegate : NSObject <NSApplicationDelegate>{
__unsafe_unretained NSWindow *_window;
}
@property (assign) IBOutlet NSWindow *window;
- (BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication *) sender;
@end
#endif

View File

@@ -0,0 +1,62 @@
/*
Copyright (c) 2005-2020 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.
*/
#import "tbbAppDelegate.h"
#if TARGET_OS_IPHONE
@implementation tbbAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
return YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
exit(EXIT_SUCCESS);
}
@end
#elif TARGET_OS_MAC
@implementation tbbAppDelegate
@synthesize window = _window;
//declared in macvideo.cpp file
extern int g_sizex, g_sizey;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
NSRect windowSize;
windowSize.size.height = g_sizey;
windowSize.size.width = g_sizex;
windowSize.origin=_window.frame.origin;
[_window setFrame:windowSize display:YES];
}
- (BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication *) sender
{
return YES;
}
@end
#endif

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>iOS</string>
<key>UIMainStoryboardFile</key>
<string>iOS</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string></string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.business</string>
<key>LSEnvironment</key>
<dict>
<key>DYLD_LIBRARY_PATH</key>
<string>Contents/Resources:.:../Resources:/tmp:$DYLD_LIBRARY_PATH</string>
<key>LIBRARY_PATH</key>
<string>Contents/Resources:.:../:/tmp:$DYLD_LIBRARY_PATH</string>
</dict>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright 2005-2020 Intel Corporation. All Rights Reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

View File

@@ -0,0 +1,32 @@
/*
Copyright (c) 2005-2020 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.
*/
//
// Prefix header for all source files of the 'tbbExample' target in the 'tbbExample' project
//
#import <Availability.h>
#if TARGET_OS_IPHONE
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif
#elif TARGET_OS_MAC
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif
#endif

View File

@@ -0,0 +1,382 @@
/*
Copyright (c) 2005-2020 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.
*/
// Uncomment next line to disable shared memory features if you do not have libXext
// (http://www.xfree86.org/current/mit-shm.html)
//#define X_NOSHMEM
// Note that it may happen that the build environment supports the shared-memory extension
// (so there's no build-time reason to disable the relevant code by defining X_NOSHMEM),
// but that using shared memory still fails at run time.
// This situation will (ultimately) cause the error handler set by XSetErrorHandler()
// to be invoked with XErrorEvent::minor_code==X_ShmAttach. The code below tries to make
// such a determination at XShmAttach() time, which seems plausible, but unfortunately
// it has also been observed in a specific environment that the error may be reported
// at a later time instead, even after video::init_window() has returned.
// It is not clear whether this may happen in that way in any environment where it might
// depend on the kind of display, e.g., local vs. over "ssh -X", so #define'ing X_NOSHMEM
// may not always be the appropriate solution, therefore an environment variable
// has been introduced to disable shared memory at run time.
// A diagnostic has been added to advise the user about possible workarounds.
// X_ShmAttach macro was changed to 1 due to recent changes to X11/extensions/XShm.h header.
#include "video.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <sys/time.h>
#include <signal.h>
#include <pthread.h>
#ifndef X_NOSHMEM
#include <errno.h>
#include <X11/extensions/XShm.h>
#include <sys/ipc.h>
#include <sys/shm.h>
static XShmSegmentInfo shmseginfo;
static Pixmap pixmap = 0;
static bool already_called_X_ShmAttach = false;
static bool already_advised_about_NOSHMEM_workarounds = false;
static const char* NOSHMEM_env_var_name = "TBB_EXAMPLES_X_NOSHMEM";
#endif
static char *display_name = NULL;
static Display *dpy = NULL;
static Screen *scrn;
static Visual *vis;
static Colormap cmap;
static GC gc;
static Window win, rootW;
static int dispdepth = 0;
static XGCValues xgcv;
static XImage *ximage;
static int x_error = 0;
static int vidtype = 3;
int g_sizex, g_sizey;
static video *g_video = 0;
unsigned int *g_pImg = 0;
static int g_fps = 0;
struct timeval g_time;
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
Atom _XA_WM_DELETE_WINDOW = 0;// like in Xatom.h
///////////////////////////////////////////// public methods of video class ///////////////////////
video::video()
{
assert(g_video == 0);
g_video = this; title = "Video"; calc_fps = running = false; updating = true;
}
inline void mask2bits(unsigned int mask, unsigned int &save, depth_t &shift)
{
save = mask; if(!mask) { shift = dispdepth/3; return; }
shift = 0; while(!(mask&1)) ++shift, mask >>= 1;
int bits = 0; while(mask&1) ++bits, mask >>= 1;
shift += bits - 8;
}
int xerr_handler(Display* dpy_, XErrorEvent *error)
{
x_error = error->error_code;
if(g_video) g_video->running = false;
#ifndef X_NOSHMEM
if (error->minor_code==1/*X_ShmAttach*/ && already_called_X_ShmAttach && !already_advised_about_NOSHMEM_workarounds)
{
char err[256]; XGetErrorText(dpy_, x_error, err, 255);
fprintf(stderr, "Warning: Can't attach shared memory to display: %s (%d)\n", err, x_error);
fprintf(stderr, "If you are seeing a black output window, try setting %s environment variable to 1"
" to disable shared memory extensions (0 to re-enable, other values undefined),"
" or rebuilding with X_NOSHMEM defined in " __FILE__ "\n", NOSHMEM_env_var_name);
already_advised_about_NOSHMEM_workarounds = true;
}
#else
(void) dpy_; // warning prevention
#endif
return 0;
}
bool video::init_window(int xsize, int ysize)
{
{ //enclose local variables before fail label
g_sizex = xsize; g_sizey = ysize;
// Open the display
if (!dpy) {
dpy = XOpenDisplay(display_name);
if (!dpy) {
fprintf(stderr, "Can't open X11 display %s\n", XDisplayName(display_name));
goto fail;
}
}
int theScreen = DefaultScreen(dpy);
scrn = ScreenOfDisplay(dpy, theScreen);
dispdepth = DefaultDepth(dpy, theScreen);
XVisualInfo vinfo;
if (!( (dispdepth >= 15 && dispdepth <= 32 && XMatchVisualInfo(dpy, theScreen, dispdepth, TrueColor, &vinfo) )
|| XMatchVisualInfo(dpy, theScreen, 24, TrueColor, &vinfo)
|| XMatchVisualInfo(dpy, theScreen, 32, TrueColor, &vinfo)
|| XMatchVisualInfo(dpy, theScreen, 16, TrueColor, &vinfo)
|| XMatchVisualInfo(dpy, theScreen, 15, TrueColor, &vinfo)
)) {
fprintf(stderr, "Display has no appropriate True Color visual\n");
goto fail;
}
vis = vinfo.visual;
depth = dispdepth = vinfo.depth;
mask2bits(vinfo.red_mask, red_mask, red_shift);
mask2bits(vinfo.green_mask, green_mask, green_shift);
mask2bits(vinfo.blue_mask, blue_mask, blue_shift);
rootW = RootWindow(dpy, theScreen);
cmap = XCreateColormap(dpy, rootW, vis, AllocNone);
XSetWindowAttributes attrs;
attrs.backing_store = Always;
attrs.colormap = cmap;
attrs.event_mask = StructureNotifyMask|KeyPressMask|ButtonPressMask|ButtonReleaseMask;
attrs.background_pixel = BlackPixelOfScreen(scrn);
attrs.border_pixel = WhitePixelOfScreen(scrn);
win = XCreateWindow(dpy, rootW,
0, 0, xsize, ysize, 2,
dispdepth, InputOutput, vis,
CWBackingStore | CWColormap | CWEventMask |
CWBackPixel | CWBorderPixel,
&attrs);
if(!win) {
fprintf(stderr, "Can't create the window\n");
goto fail;
}
XSizeHints sh;
sh.flags = PSize | PMinSize | PMaxSize;
sh.width = sh.min_width = sh.max_width = xsize;
sh.height = sh.min_height = sh.max_height = ysize;
XSetStandardProperties( dpy, win, g_video->title, g_video->title, None, NULL, 0, &sh );
_XA_WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", false);
XSetWMProtocols(dpy, win, &_XA_WM_DELETE_WINDOW, 1);
gc = XCreateGC(dpy, win, 0L, &xgcv);
XMapRaised(dpy, win);
XFlush(dpy);
#ifdef X_FULLSYNC
XSynchronize(dpy, true);
#endif
XSetErrorHandler(xerr_handler);
int imgbytes = xsize*ysize*(dispdepth<=16?2:4);
const char *vidstr;
#ifndef X_NOSHMEM
int major, minor, pixmaps;
if(XShmQueryExtension(dpy) &&
XShmQueryVersion(dpy, &major, &minor, &pixmaps))
{ // Shared memory
if(NULL!=getenv(NOSHMEM_env_var_name) && 0!=strcmp("0",getenv(NOSHMEM_env_var_name))) {
goto generic;
}
shmseginfo.shmid = shmget(IPC_PRIVATE, imgbytes, IPC_CREAT|0777);
if(shmseginfo.shmid < 0) {
fprintf(stderr, "Warning: Can't get shared memory: %s\n", strerror(errno));
goto generic;
}
g_pImg = (unsigned int*)(shmseginfo.shmaddr = (char*)shmat(shmseginfo.shmid, 0, 0));
if(g_pImg == (unsigned int*)-1) {
fprintf(stderr, "Warning: Can't attach to shared memory: %s\n", strerror(errno));
shmctl(shmseginfo.shmid, IPC_RMID, NULL);
goto generic;
}
shmseginfo.readOnly = false;
if(!XShmAttach(dpy, &shmseginfo) || x_error) {
char err[256]; XGetErrorText(dpy, x_error, err, 255);
fprintf(stderr, "Warning: Can't attach shared memory to display: %s (%d)\n", err, x_error);
shmdt(shmseginfo.shmaddr); shmctl(shmseginfo.shmid, IPC_RMID, NULL);
goto generic;
}
already_called_X_ShmAttach = true;
#ifndef X_NOSHMPIX
if(pixmaps && XShmPixmapFormat(dpy) == ZPixmap)
{ // Pixmaps
vidtype = 2; vidstr = "X11 shared memory pixmap";
pixmap = XShmCreatePixmap(dpy, win, (char*)g_pImg, &shmseginfo, xsize, ysize, dispdepth);
XSetWindowBackgroundPixmap(dpy, win, pixmap);
} else
#endif//!X_NOSHMPIX
{ // Standard
vidtype = 1; vidstr = "X11 shared memory";
ximage = XShmCreateImage(dpy, vis, dispdepth,
ZPixmap, 0, &shmseginfo, xsize, ysize);
if(!ximage) {
fprintf(stderr, "Can't create the shared image\n");
goto fail;
}
assert(ximage->bytes_per_line == xsize*(dispdepth<=16?2:4));
ximage->data = shmseginfo.shmaddr;
}
} else
#endif
{
#ifndef X_NOSHMEM
generic:
#endif
vidtype = 0; vidstr = "generic X11";
g_pImg = new unsigned int[imgbytes/sizeof(int)];
ximage = XCreateImage(dpy, vis, dispdepth, ZPixmap, 0, (char*)g_pImg, xsize, ysize, 32, imgbytes/ysize);
if(!ximage) {
fprintf(stderr, "Can't create the image\n");
goto fail;
}
}
if( ximage ) {
// Note: It may be more efficient to adopt the server's byte order
// and swap once per get_color() call instead of once per pixel.
const uint32_t probe = 0x03020100;
const bool big_endian = (((const char*)(&probe))[0]==0x03);
ximage->byte_order = big_endian ? MSBFirst : LSBFirst;
}
printf("Note: using %s with %s visual for %d-bit color depth\n", vidstr, vis==DefaultVisual(dpy, theScreen)?"default":"non-default", dispdepth);
running = true;
return true;
} // end of enclosing local variables
fail:
terminate(); init_console();
return false;
}
bool video::init_console()
{
if(!g_pImg && g_sizex && g_sizey) {
dispdepth = 24; red_shift = 16; vidtype = 3; // fake video
g_pImg = new unsigned int[g_sizex*g_sizey];
running = true;
}
return true;
}
void video::terminate()
{
running = false;
if(dpy) {
vidtype = 3; // stop video
if(threaded) { pthread_mutex_lock(&g_mutex); pthread_mutex_unlock(&g_mutex); }
if(ximage) { XDestroyImage(ximage); ximage = 0; g_pImg = 0; } // it frees g_pImg for vidtype == 0
#ifndef X_NOSHMEM
if(pixmap) XFreePixmap(dpy, pixmap);
if(shmseginfo.shmaddr) { XShmDetach(dpy, &shmseginfo); shmdt(shmseginfo.shmaddr); g_pImg = 0; }
if(shmseginfo.shmid >= 0) shmctl(shmseginfo.shmid, IPC_RMID, NULL);
#endif
if(gc) XFreeGC(dpy, gc);
if(win) XDestroyWindow(dpy, win);
XCloseDisplay(dpy); dpy = 0;
}
if(g_pImg) { delete[] g_pImg; g_pImg = 0; } // if was allocated for console mode
}
video::~video()
{
if(g_video) terminate();
g_video = 0;
}
//! Do standard event loop
void video::main_loop()
{
struct timezone tz; gettimeofday(&g_time, &tz);
on_process();
}
//! Check for pending events once
bool video::next_frame()
{
if(!running) return false;
//! try acquire mutex if threaded code, returns on failure
if(vidtype == 3 || threaded && pthread_mutex_trylock(&g_mutex))
return running;
//! Refresh screen picture
g_fps++;
#ifndef X_NOSHMPIX
if(vidtype == 2 && updating) XClearWindow(dpy, win);
#endif
while( XPending(dpy) ) {
XEvent report; XNextEvent(dpy, &report);
switch( report.type ) {
case ClientMessage:
if(report.xclient.format != 32 || report.xclient.data.l[0] != _XA_WM_DELETE_WINDOW) break;
case DestroyNotify:
running = false;
case KeyPress:
on_key( XLookupKeysym(&report.xkey, 0) ); break;
case ButtonPress:
on_mouse( report.xbutton.x, report.xbutton.y, report.xbutton.button ); break;
case ButtonRelease:
on_mouse( report.xbutton.x, report.xbutton.y, -report.xbutton.button ); break;
}
}
struct timezone tz; struct timeval now_time; gettimeofday(&now_time, &tz);
double sec = (now_time.tv_sec+1.0*now_time.tv_usec/1000000.0) - (g_time.tv_sec+1.0*g_time.tv_usec/1000000.0);
if(sec > 1) {
memcpy(&g_time, &now_time, sizeof(g_time));
if(calc_fps) {
double fps = g_fps; g_fps = 0;
char buffer[256]; snprintf(buffer, 256, "%s%s: %d fps", title, updating?"":" (no updating)", int(fps/sec));
XStoreName(dpy, win, buffer);
}
#ifndef X_FULLSYNC
XSync(dpy, false); // It is often better then using XSynchronize(dpy, true)
#endif//X_FULLSYNC
}
if(threaded) pthread_mutex_unlock(&g_mutex);
return true;
}
//! Change window title
void video::show_title()
{
if(vidtype < 3)
XStoreName(dpy, win, title);
}
drawing_area::drawing_area(int x, int y, int sizex, int sizey)
: base_index(y*g_sizex + x), max_index(g_sizex*g_sizey), index_stride(g_sizex),
pixel_depth(dispdepth), ptr32(g_pImg), start_x(x), start_y(y), size_x(sizex), size_y(sizey)
{
assert(x < g_sizex); assert(y < g_sizey);
assert(x+sizex <= g_sizex); assert(y+sizey <= g_sizey);
index = base_index; // current index
}
void drawing_area::update()
{
if(!g_video->updating) return;
#ifndef X_NOSHMEM
switch(vidtype) {
case 0:
#endif
pthread_mutex_lock(&g_mutex);
if(vidtype == 0) XPutImage(dpy, win, gc, ximage, start_x, start_y, start_x, start_y, size_x, size_y);
pthread_mutex_unlock(&g_mutex);
#ifndef X_NOSHMEM
break;
case 1:
pthread_mutex_lock(&g_mutex);
if(vidtype == 1) XShmPutImage(dpy, win, gc, ximage, start_x, start_y, start_x, start_y, size_x, size_y, false);
pthread_mutex_unlock(&g_mutex);
break;
/*case 2: make it in next_frame(); break;*/
}
#endif
}

View File

@@ -0,0 +1,399 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks. Common source code for samples</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEMAAAAsCAYAAAA+aAX8AAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAALiIAAC4iAari3ZIAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVh
ZHlxyWU8AAAIN0lEQVRoQ+WaCaxdUxSGW2ouatZWaVS15nkqkZhSVERQglLEPCam1BCixhqqCKUS
NIiYpxhqHmouIeaY5ylFzA/v1fev8+/j3N5737v3vtf3buNP/uy9/7X2Ovuse4a997m9mgltbW2L
wRHwcHgFfAx+AH+GCb/BT2fNmvUk5ZXwYOrrOsTcCU5CJ74pPBJeA5+Bn8LfOLmagf/f8Af4NrwD
ngg3wdTHh2pOMMB1Gejx8AE4M85mNqD/A7+D78GXkXQFTIMPwUfhdPg6/AxWTRw29b8QruPD9zwY
zPrwHPi2xxmg3QrfgDfD05BGU24EB1HvC3s7REXgtwDsDzeEY+Ak+AJsUfwE2sJdcBN37V4whiU4
+KGUM2JEBtpzUInZEa5g9y4FcYfAo+GLPmwOND2HFrXrnAUHWgnq0vzDB2+Bt0H9coPs1m3gmNvD
ZyITBu234Jp26XoQfCC80sfTAXVv7wOXskuPgnHoSvnTw9P49MDdyOauAQEXhWdC4Vd4ARxmc1OB
cW0Gv3U+lJDvKFa0ufMg4GXwR3gs7J57sRNoaWnR2+znLB2RkKds6jwItvbckIQiGO+eTkSby71t
qh100qtsUCJxmmpSw5i2gWebR1jWm2047T1gf0vyfViJEKi/TtHua7wMdNJs8U/zDzjUpqYA47k4
O704wY+kUZ2P+glQc5ldac9j323sF1cH2EB6h8BxYZdbRDeDOJ16UBJiHDFuMMdYbhjEGA8DxJ4h
jXIemmMpz6ccqbZ1JUlT/3SrHC+9XeB0MjzV9RHqKFAXVg2nBkH/lxxO8aZYbhjEKEuGQH1BuCKc
z1IAN61jAtiut1wZ+ByIkwa6r9t6ZmhSFZw9eL0gxiMw4SLLDYMYFZNRDbhpcpgwzXI5MOqSEvKM
Ue8D+xU4r/Xe+C8HB1ThkhFgNqAXk6FVqyZuA1LcItBXQd+WUvf6YMslwFZvMs7KvMP/SculwKa3
hfYPPsZpfsvS9QD9PRHbcOmUC9J+H2qfoRJ/0MHgFhHIQC8mQ8twxZ0Ji099vSGegn/TP0BdD/Db
Ycn0nna9yZiceQcetFwKDE/4oNtZCtDeXHoC7dWlU1Uyvs7U6sBHJ7FaBAPU82TYJUAzFnCU+1mq
COyfwGLi6k3G05l34BrL/wFxjA/0mKUcaNqBKiJODHclQ3sLCVqZprfEvVCLtThhiskRDFAvXhnv
QPlfi5uW7ytTL14Nr0Bd1pfDXy1Lv93h6koGLstCLR/SuPJ5SQBBD8hPZATbWs6BrdZk7B4dDNpT
Mjkw3bL0YjLOsxygPUWDyExtD1GNV6JAeyTUBlDCKtbrScYxhfjyj1s+B9o+dnifIj94AnpNyaC9
f3QwkNJCTnjOsvRiMi6xrHiaA3ycyYFNbcqBpisl/aoHWaspGdg03uIc43mb/gOilt3CREslQG80
GedmlkC1KyNPBnU9wOPWMp6Aut0S74HfwIQJ7ldTMjBPdBIiGWC0TRkQlseWNmR2tlwC9DmZjEmW
pQ/zOAKqtwdcrnW/DpOBPtp9Ii6F9lhL1yWIo2zUvVhxzYHeLVcG/QfT/iuTA3qwan+zGndVP8p2
k4G8E/wLW4D6PxTlnxgwaDEjaMe6n+USYOvqZKTbUrjQcor3ZSYHRtjULvCrmgwkfY5oRc9B+3Cb
S4FhIhS+gAtZLgH9Y6GWuQU6mwx9IEqYajlA+47CsZ6lGovFBDTNkA9xM4CmpXsAWySDUrPjqZQl
QBsfnSoB41UKAvS9ouJmDfpaDpTQ2WRcXYinCZm+pdyEtDClPgLloP0unABPp3lrpoZ+KkWskSgP
sVZMhlat2t7LQftE2aoCh0sVBOheXclyCYjTp7W19bUsZAQtJuPLTA39gOhg0D7PJtny1xj1tWA+
sUpAG2j7mZaqAh9tzPSVP+XStL+w/qY1XRlfWdOSYXvp7QKnU6Ayqk4jLZcB2zD4gv1iu52qkvG5
NKPsyrCuPs9aDtDeDr4EtS7RRyXNCgfYLPtYfoC33D0Hul6tE6jOfvsMhVqaT8PWG85PXR+WxlOP
pHUIHPNXDsif7NWAT773STdlX6vK4ebi4WRgWybZqFe86tBXUAw4BL+S7UTautTXo9yFcjdKPbsq
PuQTsKdbZ16YLzZrAgdRRvXLCF/Big/R/wXInn5dffdMt8opNs214Bz6cyqNbUDRcZwTIWjDt3m+
XtcBxq3pvL6p6mFftlFUE+i8JPxRCRGoawVbcVepGcF4V4eTGPNPHv+7NjUGAhzmQOl20fyhphlg
T4CxLcQw9WC9Gxb3P4Q37NY4CHJXCuhSW3JnwEXs0qNgSHqVbw210ZP2XwK0A65/6C6NgziaAU5X
wCIUHB4H86227gKH1+JtL3gd1N5sCdACbgZo5rtgnQKx+hLs/ixsdjBXBd2TtyKNhUOp1/dprgMQ
rx9x16fcn1KbttrIyf9OkICWw1KApvY2YyXbpSBobKf7OGXApFtI+5d3Qq1BDoL6V87GcDVc9Ivq
E4D+bjTQbc1i9demreDu8Ch0ffG6hdnmDMrvFbsSsAXczIGk3fwb4VYe+pwBB9Angkd83ADtqgkq
AjetdTTV1icDlfl+Qi3AP4elHEjaDXscHgFjPdNt4ID6S9B9sNLiKoelmuFuJbCpDJi+hvqz2qFw
iIfWc2AQusxPgvq484vH2eUgtpYHH0Hteeqb75ZwMQ+j+cDg9PlwFDwd6o9sr0KtbWI/tSPgp32M
76H+s6mNX3030df5neGq1OtbZDUbOIlFoFaha0L9j0qfCHeAerDqVtODU8+hNThZfR1fHHbpG6kx
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks.<br>Common source code for samples</h1>
</div>
<p>
This directory contains common code that is used in the Intel&reg; Threading Building Blocks (Intel&reg; TBB) samples.
<br>
This code is not intended to be used directly. It is incorporated automatically by the examples that need it.
</p>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="gui/">gui</a>
<dd>
GUI code for examples that have graphical user interfaces. Currently supports:
<ul>
<li>GDI+*, DirectDraw*, Direct2D* (Windows* systems)
<li>OpenGL* (macOS* systems)
<li>X window (Linux* or macOS* systems)
</ul>
See the examples that use the GUI
(<a href="../graph/stereo/readme.html">stereo</a>,
<a href="../parallel_for/tachyon/readme.html">tachyon</a>,
<a href="../parallel_for/seismic/readme.html">seismic</a>,
<a href="../task_arena/fractal/readme.html">fractal</a>)
for more details.
</dl>
<dl>
<dt><a href="utility/">utility</a>
<dd>Common driver and utility code for examples. Currently provides:
<ul>
<li>class FastRandom - a random number generator that uses linear congruential method
(<a href="utility/fast_random.h">fast_random.h</a>)
<li>class thread_number_range - a class to specify the numbers of threads an example should use
(<a href="utility/utility.h">utility.h</a>)
<li>support for command line interface - class cli_argument_pack and function parse_cli_arguments
(<a href="utility/utility.h">utility.h</a>)
</ul>
</dl>
</div>
</div>
<div class="changes">
<div class="h3-alike">Common information</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<br>
<div class="h4-alike">Number of threads</div>
<p>
Most Intel TBB examples allow to specify <i>n-of-threads</i>, the set of thread numbers that should be used to run an example.
<br>Usually, it is a range of the form <i>low[:high[:(+|*|#)S]]</i>, where <i>low</i> and optional <i>high</i>
are non-negative integers or 'auto' for the default choice, and optional step expression <i>(+|*|#)S</i>
specifies how thread numbers are chosen within the range:
<ul>
<li>With <i>+/*</i>, the previous number is incremented/multiplied by <i>S</i>.
E.g., expression '12:16:+1' means 12,13,14,15,16 threads, and '1:16:*2' means 1,2,4,8,16 threads.
<li>With <i>#</i>, <i>S</i> is the desired number of steps between any subsequent powers of 2;
it must be a power of 2 on its own, with most meaningful values being 2, 4, and 8.
For a given number of threads, the actual step value is computed as the quotient
of the nearest smaller power of 2 divided by the number of steps, but is at least 1.
E.g., '1:32:#4' means 1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32 threads;
note the step doubling at 8 and 16 to keep 4 steps between powers of 2.
</ul>
A default value for the number of threads can be customized in an example. If not customized, it is '1:auto:#4'.
The 'auto' parameter is substituted with a value returned by a specified function
(this function is typically <code>utility::get_default_num_threads()</code>, which returns a copy of
constant that was initialized with <code>tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism)</code>
at the start of the program).
</p>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a>
<hr>
<div class="changes">
<div class="h3-alike">Legal Information:</div>
<input type="checkbox">
<div class="show-hide">
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PlatformToolset Condition="Exists('$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\Intel C++ Compiler 15.0 [Intel(R) System Studio]')">Intel C++ Compiler 15.0 [Intel(R) System Studio]</PlatformToolset>
<PlatformToolset Condition="Exists('$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\Intel C++ Compiler XE 15.0')">Intel C++ Compiler XE 15.0</PlatformToolset>
<PlatformToolset Condition="Exists('$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\Intel C++ Compiler 16.0')">Intel C++ Compiler 16.0</PlatformToolset>
<UseIntelTBB Condition="'$(UseIntelTBB)' == ''">true</UseIntelTBB>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,78 @@
/*
Copyright (c) 2005-2020 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.
*/
#ifndef FAST_RANDOM_H_
#define FAST_RANDOM_H_
namespace utility{
//------------------------------------------------------------------------
// FastRandom
//------------------------------------------------------------------------
namespace internal{
size_t GetPrime ( size_t seed );
}
//! A fast random number generator.
/** Uses linear congruential method. */
class FastRandom {
size_t x, a;
public:
//! Get a random number.
unsigned short get() {
return get(x);
}
//! Get a random number for the given seed; update the seed for next use.
unsigned short get( size_t& seed ) {
unsigned short r = (unsigned short)(seed>>16);
seed = seed*a+1;
return r;
}
//! Construct a random number generator.
FastRandom( size_t seed ) {
x = seed*internal::GetPrime(seed);
a = internal::GetPrime(x);
}
};
}
namespace utility {
namespace internal{
//! Table of primes used by fast random-number generator (FastRandom).
static const unsigned Primes[] = {
0x9e3779b1, 0xffe6cc59, 0x2109f6dd, 0x43977ab5,
0xba5703f5, 0xb495a877, 0xe1626741, 0x79695e6b,
0xbc98c09f, 0xd5bee2b3, 0x287488f9, 0x3af18231,
0x9677cd4d, 0xbe3a6929, 0xadc6a877, 0xdcf0674b,
0xbe4d6fe9, 0x5f15e201, 0x99afc3fd, 0xf3f16801,
0xe222cfff, 0x24ba5fdb, 0x0620452d, 0x79f149e3,
0xc8b93f49, 0x972702cd, 0xb07dd827, 0x6c97d5ed,
0x085a3d61, 0x46eb5ea7, 0x3d9910ed, 0x2e687b5b,
0x29609227, 0x6eb081f1, 0x0954c4e1, 0x9d114db9,
0x542acfa9, 0xb3e6bd7b, 0x0742d917, 0xe9f3ffa7,
0x54581edb, 0xf2480f45, 0x0bb9288f, 0xef1affc7,
0x85fa0ca7, 0x3ccc14db, 0xe6baf34b, 0x343377f7,
0x5ca19031, 0xe6d9293b, 0xf0a9f391, 0x5d2e980b,
0xfc411073, 0xc3749363, 0xb892d829, 0x3549366b,
0x629750ad, 0xb98294e5, 0x892d9483, 0xc235baf3,
0x3d2402a3, 0x6bdef3c9, 0xbec333cd, 0x40c9520f
};
size_t GetPrime ( size_t seed ) {
return Primes[seed%(sizeof(Primes)/sizeof(Primes[0]))];
}
}
}
#endif /* FAST_RANDOM_H_ */

View File

@@ -0,0 +1,32 @@
/*
Copyright (c) 2005-2020 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.
*/
#ifndef GET_DEFAULT_NUM_THREADS_H_
#define GET_DEFAULT_NUM_THREADS_H_
#include "tbb/global_control.h"
namespace utility {
inline int get_default_num_threads() {
#if __TBB_MIC_OFFLOAD
#pragma offload target(mic) out(default_num_threads)
#endif // __TBB_MIC_OFFLOAD
static size_t default_num_threads = tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism);
return static_cast<int>(default_num_threads);
}
}
#endif /* GET_DEFAULT_NUM_THREADS_H_ */

View File

@@ -0,0 +1,523 @@
/*
Copyright (c) 2005-2020 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.
*/
#ifndef UTILITY_H_
#define UTILITY_H_
#if __TBB_MIC_OFFLOAD
#pragma offload_attribute (push,target(mic))
#include <exception>
#include <cstdio>
#pragma offload_attribute (pop)
#endif // __TBB_MIC_OFFLOAD
#include <utility>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <sstream>
#include <numeric>
#include <stdexcept>
#include <memory>
#include <cassert>
#include <iostream>
#include <cstdlib>
// TBB headers should not be used, as some examples may need to be built without TBB.
namespace utility{
namespace internal{
#if (_MSC_VER >= 1600 || __cplusplus >= 201103L || __GXX_EXPERIMENTAL_CXX0X__) \
&& (_CPPLIB_VER || _LIBCPP_VERSION || __GLIBCXX__ && _UNIQUE_PTR_H ) \
&& (!__INTEL_COMPILER || __INTEL_COMPILER >= 1200 )
// std::unique_ptr is available, and compiler can use it
#define smart_ptr std::unique_ptr
using std::swap;
#else
#if __INTEL_COMPILER && __GXX_EXPERIMENTAL_CXX0X__
// std::unique_ptr is unavailable, so suppress std::auto_prt<> deprecation warning
#pragma warning(disable: 1478)
#endif
#define smart_ptr std::auto_ptr
// in some C++ libraries, std::swap does not work with std::auto_ptr
template<typename T>
void swap( std::auto_ptr<T>& ptr1, std::auto_ptr<T>& ptr2 ) {
std::auto_ptr<T> tmp; tmp = ptr2; ptr2 = ptr1; ptr1 = tmp;
}
#endif
//TODO: add tcs
template<class dest_type>
dest_type& string_to(std::string const& s, dest_type& result){
std::stringstream stream(s);
stream>>result;
if ((!stream)||(stream.fail())){
throw std::invalid_argument("error converting string '"+std::string(s)+"'");
}
return result;
}
template<class dest_type>
dest_type string_to(std::string const& s){
dest_type result;
return string_to(s,result);
}
template<typename>
struct is_bool { static bool value(){return false;}};
template<>
struct is_bool<bool> { static bool value(){return true;}};
class type_base {
type_base& operator=(const type_base&);
public:
const std::string name;
const std::string description;
type_base (std::string a_name, std::string a_description) : name(a_name), description(a_description) {}
virtual void parse_and_store(const std::string & s) = 0;
virtual std::string value() const = 0;
virtual smart_ptr<type_base> clone() const = 0;
virtual ~type_base(){}
};
template <typename type>
class type_impl : public type_base {
private:
type_impl(const type_impl& src) : type_base(src.name, src.description), target(src.target),
validating_function(src.validating_function) {}
type_impl& operator=(const type_impl&);
typedef bool(*validating_function_type)(const type&);
type & target;
validating_function_type validating_function;
public:
type_impl(std::string a_name, std::string a_description, type & a_target, validating_function_type a_validating_function = NULL)
: type_base (a_name,a_description), target(a_target),validating_function(a_validating_function)
{};
void parse_and_store (const std::string & s) /*override*/ {
try{
const bool is_bool = internal::is_bool<type>::value();
if (is_bool && s.empty()){
//to avoid directly assigning true
//(as it will impose additional layer of indirection)
//so, simply pass it as string
internal::string_to("1",target);
}else {
internal::string_to(s,target);
}
}catch(std::invalid_argument& e){
std::stringstream str;
str <<"'"<<s<<"' is incorrect input for argument '"<<name<<"'"
<<" ("<<e.what()<<")";
throw std::invalid_argument(str.str());
}
if (validating_function){
if (!((validating_function)(target))){
std::stringstream str;
str <<"'"<<target<<"' is invalid value for argument '"<<name<<"'";
throw std::invalid_argument(str.str());
}
}
}
template <typename t>
static bool is_null_c_str(t&){return false;}
static bool is_null_c_str(char* s){return s==NULL;}
std::string value() const /*override*/ {
std::stringstream str;
if (!is_null_c_str(target))
str<<target;
return str.str();
}
smart_ptr<type_base> clone() const /*override*/ {
return smart_ptr<type_base>(new type_impl(*this));
}
};
class argument{
private:
smart_ptr<type_base> p_type;
bool matched_;
public:
argument(argument const& other)
: p_type(other.p_type.get() ? (other.p_type->clone()).release() : NULL)
,matched_(other.matched_)
{}
argument& operator=(argument a){
this->swap(a);
return *this;
}
void swap(argument& other){
internal::swap(p_type, other.p_type);
std::swap(matched_,other.matched_);
}
template<class type>
argument(std::string a_name, std::string a_description, type& dest, bool(*a_validating_function)(const type&)= NULL)
:p_type(new type_impl<type>(a_name,a_description,dest,a_validating_function))
,matched_(false)
{}
std::string value()const{
return p_type->value();
}
std::string name()const{
return p_type->name;
}
std::string description() const{
return p_type->description;
}
void parse_and_store(const std::string & s){
p_type->parse_and_store(s);
matched_=true;
}
bool is_matched() const{return matched_;}
};
} // namespace internal
class cli_argument_pack{
typedef std::map<std::string,internal::argument> args_map_type;
typedef std::vector<std::string> args_display_order_type;
typedef std::vector<std::string> positional_arg_names_type;
private:
args_map_type args_map;
args_display_order_type args_display_order;
positional_arg_names_type positional_arg_names;
std::set<std::string> bool_args_names;
private:
void add_arg(internal::argument const& a){
std::pair<args_map_type::iterator, bool> result = args_map.insert(std::make_pair(a.name(),a));
if (!result.second){
throw std::invalid_argument("argument with name: '"+a.name()+"' already registered");
}
args_display_order.push_back(a.name());
}
public:
template<typename type>
cli_argument_pack& arg(type& dest,std::string const& name, std::string const& description, bool(*validate)(const type &)= NULL){
internal::argument a(name,description,dest,validate);
add_arg(a);
if (internal::is_bool<type>::value()){
bool_args_names.insert(name);
}
return *this;
}
//Positional means that argument name can be omitted in actual CL
//only key to match values for parameters with
template<typename type>
cli_argument_pack& positional_arg(type& dest,std::string const& name, std::string const& description, bool(*validate)(const type &)= NULL){
internal::argument a(name,description,dest,validate);
add_arg(a);
if (internal::is_bool<type>::value()){
bool_args_names.insert(name);
}
positional_arg_names.push_back(name);
return *this;
}
void parse(std::size_t argc, char const* argv[]){
{
std::size_t current_positional_index=0;
for (std::size_t j=1;j<argc;j++){
internal::argument* pa = NULL;
std::string argument_value;
const char * const begin=argv[j];
const char * const end=begin+std::strlen(argv[j]);
const char * const assign_sign = std::find(begin,end,'=');
struct throw_unknown_parameter{ static void _(std::string const& location){
throw std::invalid_argument(std::string("unknown parameter starting at:'")+location+"'");
}};
//first try to interpret it like parameter=value string
if (assign_sign!=end){
std::string name_found = std::string(begin,assign_sign);
args_map_type::iterator it = args_map.find(name_found );
if(it!=args_map.end()){
pa= &((*it).second);
argument_value = std::string(assign_sign+1,end);
}else {
throw_unknown_parameter::_(argv[j]);
}
}
//then see is it a named flag
else{
args_map_type::iterator it = args_map.find(argv[j] );
if(it!=args_map.end()){
pa= &((*it).second);
argument_value = "";
}
//then try it as positional argument without name specified
else if (current_positional_index < positional_arg_names.size()){
std::stringstream str(argv[j]);
args_map_type::iterator found_positional_arg = args_map.find(positional_arg_names.at(current_positional_index));
//TODO: probably use of smarter assert would help here
assert(found_positional_arg!=args_map.end()/*&&"positional_arg_names and args_map are out of sync"*/);
if (found_positional_arg==args_map.end()){
throw std::logic_error("positional_arg_names and args_map are out of sync");
}
pa= &((*found_positional_arg).second);
argument_value = argv[j];
current_positional_index++;
}else {
//TODO: add tc to check
throw_unknown_parameter::_(argv[j]);
}
}
assert(pa);
if (pa->is_matched()){
throw std::invalid_argument(std::string("several values specified for: '")+pa->name()+"' argument");
}
pa->parse_and_store(argument_value);
}
}
}
std::string usage_string(const std::string& binary_name)const{
std::string command_line_params;
std::string summary_description;
for (args_display_order_type::const_iterator it = args_display_order.begin();it!=args_display_order.end();++it){
const bool is_bool = (0!=bool_args_names.count((*it)));
args_map_type::const_iterator argument_it = args_map.find(*it);
//TODO: probably use of smarter assert would help here
assert(argument_it!=args_map.end()/*&&"args_display_order and args_map are out of sync"*/);
if (argument_it==args_map.end()){
throw std::logic_error("args_display_order and args_map are out of sync");
}
const internal::argument & a = (*argument_it).second;
command_line_params +=" [" + a.name() + (is_bool ?"":"=value")+ "]";
summary_description +=" " + a.name() + " - " + a.description() +" ("+a.value() +")" + "\n";
}
std::string positional_arg_cl;
for (positional_arg_names_type::const_iterator it = positional_arg_names.begin();it!=positional_arg_names.end();++it){
positional_arg_cl +=" ["+(*it);
}
for (std::size_t i=0;i<positional_arg_names.size();++i){
positional_arg_cl+="]";
}
command_line_params+=positional_arg_cl;
std::stringstream str;
using std::endl;
str << " Program usage is:" << endl
<< " " << binary_name << command_line_params
<< endl << endl
<< " where:" << endl
<< summary_description
;
return str.str();
}
}; // class cli_argument_pack
namespace internal {
template<typename T>
bool is_power_of_2( T val ) {
size_t intval = size_t(val);
return (intval&(intval-1)) == size_t(0);
}
int step_function_plus(int previous, double step){
return static_cast<int>(previous+step);
}
int step_function_multiply(int previous, double multiply){
return static_cast<int>(previous*multiply);
}
// "Power-of-2 ladder": nsteps is the desired number of steps between any subsequent powers of 2.
// The actual step is the quotient of the nearest smaller power of 2 divided by that number (but at least 1).
// E.g., '1:32:#4' means 1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32
int step_function_power2_ladder(int previous, double nsteps){
int steps = int(nsteps);
assert( is_power_of_2(steps) ); // must be a power of 2
// The actual step is 1 until the value is twice as big as nsteps
if( previous < 2*steps )
return previous+1;
// calculate the previous power of 2
int prev_power2 = previous/2; // start with half the given value
int rshift = 1; // and with the shift of 1;
while( int shifted = prev_power2>>rshift ) { // shift the value right; while the result is non-zero,
prev_power2 |= shifted; // add the bits set in 'shifted';
rshift <<= 1; // double the shift, as twice as many top bits are set;
} // repeat.
++prev_power2; // all low bits set; now it's just one less than the desired power of 2
assert( is_power_of_2(prev_power2) );
assert( (prev_power2<=previous)&&(2*prev_power2>previous) );
// The actual step value is the previous power of 2 divided by steps
return previous + (prev_power2/steps);
}
typedef int (* step_function_ptr_type)(int,double);
struct step_function_descriptor {
char mnemonic;
step_function_ptr_type function;
public:
step_function_descriptor(char a_mnemonic, step_function_ptr_type a_function) : mnemonic(a_mnemonic), function(a_function) {}
private:
void operator=(step_function_descriptor const&);
};
step_function_descriptor step_function_descriptors[] = {
step_function_descriptor('*',step_function_multiply),
step_function_descriptor('+',step_function_plus),
step_function_descriptor('#',step_function_power2_ladder)
};
template<typename T, size_t N>
inline size_t array_length(const T(&)[N])
{
return N;
}
struct thread_range_step {
step_function_ptr_type step_function;
double step_function_argument;
thread_range_step ( step_function_ptr_type step_function_, double step_function_argument_)
:step_function(step_function_),step_function_argument(step_function_argument_)
{
if (!step_function_)
throw std::invalid_argument("step_function for thread range step should not be NULL");
}
int operator()(int previous)const {
assert(0<=previous); // test 0<=first and loop discipline
const int ret = step_function(previous,step_function_argument);
assert(previous<ret);
return ret;
}
friend std::istream& operator>>(std::istream& input_stream, thread_range_step& step){
char function_char;
double function_argument;
input_stream >> function_char >> function_argument;
size_t i = 0;
while ((i<array_length(step_function_descriptors)) && (step_function_descriptors[i].mnemonic!=function_char)) ++i;
if (i >= array_length(step_function_descriptors)){
throw std::invalid_argument("unknown step function mnemonic: "+std::string(1,function_char));
} else if ((function_char=='#') && !is_power_of_2(function_argument)) {
throw std::invalid_argument("the argument of # should be a power of 2");
}
step.step_function = step_function_descriptors[i].function;
step.step_function_argument = function_argument;
return input_stream;
}
};
} // namespace internal
struct thread_number_range{
int (*auto_number_of_threads)();
int first; // 0<=first (0 can be used as a special value)
int last; // first<=last
::utility::internal::thread_range_step step;
thread_number_range( int (*auto_number_of_threads_)(),int low_=1, int high_=-1
, ::utility::internal::thread_range_step step_ = ::utility::internal::thread_range_step(::utility::internal::step_function_power2_ladder,4)
)
: auto_number_of_threads(auto_number_of_threads_), first(low_), last((high_>-1) ? high_ : auto_number_of_threads_())
,step(step_)
{
if (first<0) {
throw std::invalid_argument("negative value not allowed");
}
if (first>last) {
throw std::invalid_argument("decreasing sequence not allowed");
}
}
friend std::istream& operator>>(std::istream& i, thread_number_range& range){
try{
std::string s;
i>>s;
struct string_to_number_of_threads{
int auto_value;
string_to_number_of_threads(int auto_value_):auto_value(auto_value_){}
int operator()(const std::string & value)const{
return (value=="auto")? auto_value : internal::string_to<int>(value);
}
};
string_to_number_of_threads string_to_number_of_threads(range.auto_number_of_threads());
int low, high;
std::size_t colon = s.find(':');
if ( colon == std::string::npos ){
low = high = string_to_number_of_threads(s);
} else {
//it is a range
std::size_t second_colon = s.find(':',colon+1);
low = string_to_number_of_threads(std::string(s, 0, colon)); //not copying the colon
high = string_to_number_of_threads(std::string(s, colon+1, second_colon - (colon+1))); //not copying the colons
if (second_colon != std::string::npos){
internal::string_to(std::string(s,second_colon + 1),range.step);
}
}
range = thread_number_range(range.auto_number_of_threads,low,high,range.step);
}catch(std::invalid_argument&){
i.setstate(std::ios::failbit);
throw;
}
return i;
}
friend std::ostream& operator<<(std::ostream& o, thread_number_range const& range){
using namespace internal;
size_t i = 0;
for (; i < array_length(step_function_descriptors) && step_function_descriptors[i].function != range.step.step_function; ++i ) {}
if (i >= array_length(step_function_descriptors)){
throw std::invalid_argument("unknown step function for thread range");
}
o<<range.first<<":"<<range.last<<":"<<step_function_descriptors[i].mnemonic<<range.step.step_function_argument;
return o;
}
}; // struct thread_number_range
//TODO: fix unused warning here
//TODO: update the thread range description in the .html files
static const char* thread_number_range_desc="number of threads to use; a range of the form low[:high[:(+|*|#)step]],"
"\n\twhere low and optional high are non-negative integers or 'auto' for the default choice,"
"\n\tand optional step expression specifies how thread numbers are chosen within the range."
"\n\tSee examples/common/index.html for detailed description."
;
inline void report_elapsed_time(double seconds){
std::cout<<"elapsed time : "<<seconds<<" seconds"<<std::endl;
}
inline void report_skipped(){
std::cout<<"skip"<<std::endl;
}
inline void parse_cli_arguments(int argc, const char* argv[], utility::cli_argument_pack cli_pack){
bool show_help = false;
cli_pack.arg(show_help,"-h","show this message");
bool invalid_input=false;
try {
cli_pack.parse(argc,argv);
}catch(std::exception& e){
std::cerr
<<"error occurred while parsing command line."<<std::endl
<<"error text: "<<e.what()<<std::endl
<<std::flush;
invalid_input =true;
}
if (show_help || invalid_input){
std::cout<<cli_pack.usage_string(argv[0])<<std::flush;
std::exit(0);
}
}
inline void parse_cli_arguments(int argc, char* argv[], utility::cli_argument_pack cli_pack){
parse_cli_arguments(argc, const_cast<const char**>(argv), cli_pack);
}
}
#endif /* UTILITY_H_ */

View File

@@ -0,0 +1,47 @@
# Copyright (c) 2005-2020 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.
# Common Makefile that builds and runs example.
# Just specify your program basename
PROG=Count_Strings
ARGS=
PERF_RUN_ARGS=auto 10000000 silent
# The C++ compiler options
# Trying to find if icl.exe is set
CXX1 = $(TBB_CXX)-
CXX2 = $(CXX1:icl.exe-=icl.exe)
CXX = $(CXX2:-=cl.exe)
MYCXXFLAGS = /TP /EHsc /W3 /nologo /D _CONSOLE /D _MBCS /D WIN32 $(CXXFLAGS)
MYLDFLAGS =/INCREMENTAL:NO /NOLOGO /DEBUG /FIXED:NO $(LDFLAGS)
all: release test
release: compiler_check
$(CXX) *.cpp /MD /O2 /D NDEBUG $(MYCXXFLAGS) /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
debug: compiler_check
$(CXX) *.cpp /MDd /Od /Zi /D TBB_USE_DEBUG /D _DEBUG $(MYCXXFLAGS) /link tbb_debug.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
clean:
@cmd.exe /C del $(PROG).exe *.obj *.?db *.manifest
test:
$(PROG) $(ARGS)
compiler_check:
@echo compiler_test>compiler_test && @$(CXX) /E compiler_test >nul 2>&1 || echo "$(CXX) command not found. Check if CXX=$(CXX) is set properly"
@cmd.exe /C del compiler_test
perf_build: release
perf_run:
$(PROG) $(PERF_RUN_ARGS)

View File

@@ -0,0 +1,232 @@
/*
Copyright (c) 2005-2020 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.
*/
// Workaround for ICC 11.0 not finding __sync_fetch_and_add_4 on some of the Linux platforms.
#if __linux__ && defined(__INTEL_COMPILER)
#define __sync_fetch_and_add(ptr,addend) _InterlockedExchangeAdd(const_cast<void*>(reinterpret_cast<volatile void*>(ptr)), addend)
#endif
#include <string>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <cstdio>
#include "tbb/concurrent_hash_map.h"
#include "tbb/blocked_range.h"
#include "tbb/parallel_for.h"
#include "tbb/tick_count.h"
#include "tbb/tbb_allocator.h"
#include "tbb/global_control.h"
#include "../../common/utility/utility.h"
#include "../../common/utility/get_default_num_threads.h"
//! String type with scalable allocator.
/** On platforms with non-scalable default memory allocators, the example scales
better if the string allocator is changed to tbb::tbb_allocator<char>. */
typedef std::basic_string<char,std::char_traits<char>,tbb::tbb_allocator<char> > MyString;
using namespace tbb;
using namespace std;
//! Set to true to counts.
static bool verbose = false;
static bool silent = false;
//! Problem size
long N = 1000000;
const int size_factor = 2;
//! A concurrent hash table that maps strings to ints.
typedef concurrent_hash_map<MyString,int> StringTable;
//! Function object for counting occurrences of strings.
struct Tally {
StringTable& table;
Tally( StringTable& table_ ) : table(table_) {}
void operator()( const blocked_range<MyString*> range ) const {
for( MyString* p=range.begin(); p!=range.end(); ++p ) {
StringTable::accessor a;
table.insert( a, *p );
a->second += 1;
}
}
};
static MyString* Data;
static void CountOccurrences(int nthreads) {
StringTable table;
tick_count t0 = tick_count::now();
parallel_for( blocked_range<MyString*>( Data, Data+N, 1000 ), Tally(table) );
tick_count t1 = tick_count::now();
int n = 0;
for( StringTable::iterator i=table.begin(); i!=table.end(); ++i ) {
if( verbose && nthreads )
printf("%s %d\n",i->first.c_str(),i->second);
n += i->second;
}
if ( !silent ) printf("total = %d unique = %u time = %g\n", n, unsigned(table.size()), (t1-t0).seconds());
}
/// Generator of random words
struct Sound {
const char *chars;
int rates[3];// beginning, middle, ending
};
Sound Vowels[] = {
{"e", {445,6220,1762}}, {"a", {704,5262,514}}, {"i", {402,5224,162}}, {"o", {248,3726,191}},
{"u", {155,1669,23}}, {"y", {4,400,989}}, {"io", {5,512,18}}, {"ia", {1,329,111}},
{"ea", {21,370,16}}, {"ou", {32,298,4}}, {"ie", {0,177,140}}, {"ee", {2,183,57}},
{"ai", {17,206,7}}, {"oo", {1,215,7}}, {"au", {40,111,2}}, {"ua", {0,102,4}},
{"ui", {0,104,1}}, {"ei", {6,94,3}}, {"ue", {0,67,28}}, {"ay", {1,42,52}},
{"ey", {1,14,80}}, {"oa", {5,84,3}}, {"oi", {2,81,1}}, {"eo", {1,71,5}},
{"iou", {0,61,0}}, {"oe", {2,46,9}}, {"eu", {12,43,0}}, {"iu", {0,45,0}},
{"ya", {12,19,5}}, {"ae", {7,18,10}}, {"oy", {0,10,13}}, {"ye", {8,7,7}},
{"ion", {0,0,20}}, {"ing", {0,0,20}}, {"ium", {0,0,10}}, {"er", {0,0,20}}
};
Sound Consonants[] = {
{"r", {483,1414,1110}}, {"n", {312,1548,1114}}, {"t", {363,1653,251}}, {"l", {424,1341,489}},
{"c", {734,735,260}}, {"m", {732,785,161}}, {"d", {558,612,389}}, {"s", {574,570,405}},
{"p", {519,361,98}}, {"b", {528,356,30}}, {"v", {197,598,16}}, {"ss", {3,191,567}},
{"g", {285,430,42}}, {"st", {142,323,180}}, {"h", {470,89,30}}, {"nt", {0,350,231}},
{"ng", {0,117,442}}, {"f", {319,194,19}}, {"ll", {1,414,83}}, {"w", {249,131,64}},
{"k", {154,179,47}}, {"nd", {0,279,92}}, {"bl", {62,235,0}}, {"z", {35,223,16}},
{"sh", {112,69,79}}, {"ch", {139,95,25}}, {"th", {70,143,39}}, {"tt", {0,219,19}},
{"tr", {131,104,0}}, {"pr", {186,41,0}}, {"nc", {0,223,2}}, {"j", {184,32,1}},
{"nn", {0,188,20}}, {"rt", {0,148,51}}, {"ct", {0,160,29}}, {"rr", {0,182,3}},
{"gr", {98,87,0}}, {"ck", {0,92,86}}, {"rd", {0,81,88}}, {"x", {8,102,48}},
{"ph", {47,101,10}}, {"br", {115,43,0}}, {"cr", {92,60,0}}, {"rm", {0,131,18}},
{"ns", {0,124,18}}, {"sp", {81,55,4}}, {"sm", {25,29,85}}, {"sc", {53,83,1}},
{"rn", {0,100,30}}, {"cl", {78,42,0}}, {"mm", {0,116,0}}, {"pp", {0,114,2}},
{"mp", {0,99,14}}, {"rs", {0,96,16}}, /*{"q", {52,57,1}},*/ {"rl", {0,97,7}},
{"rg", {0,81,15}}, {"pl", {56,39,0}}, {"sn", {32,62,1}}, {"str", {38,56,0}},
{"dr", {47,44,0}}, {"fl", {77,13,1}}, {"fr", {77,11,0}}, {"ld", {0,47,38}},
{"ff", {0,62,20}}, {"lt", {0,61,19}}, {"rb", {0,75,4}}, {"mb", {0,72,7}},
{"rc", {0,76,1}}, {"gg", {0,74,1}}, {"pt", {1,56,10}}, {"bb", {0,64,1}},
{"sl", {48,17,0}}, {"dd", {0,59,2}}, {"gn", {3,50,4}}, {"rk", {0,30,28}},
{"nk", {0,35,20}}, {"gl", {40,14,0}}, {"wh", {45,6,0}}, {"ntr", {0,50,0}},
{"rv", {0,47,1}}, {"ght", {0,19,29}}, {"sk", {23,17,5}}, {"nf", {0,46,0}},
{"cc", {0,45,0}}, {"ln", {0,41,0}}, {"sw", {36,4,0}}, {"rp", {0,36,4}},
{"dn", {0,38,0}}, {"ps", {14,19,5}}, {"nv", {0,38,0}}, {"tch", {0,21,16}},
{"nch", {0,26,11}}, {"lv", {0,35,0}}, {"wn", {0,14,21}}, {"rf", {0,32,3}},
{"lm", {0,30,5}}, {"dg", {0,34,0}}, {"ft", {0,18,15}}, {"scr", {23,10,0}},
{"rch", {0,24,6}}, {"rth", {0,23,7}}, {"rh", {13,15,0}}, {"mpl", {0,29,0}},
{"cs", {0,1,27}}, {"gh", {4,10,13}}, {"ls", {0,23,3}}, {"ndr", {0,25,0}},
{"tl", {0,23,1}}, {"ngl", {0,25,0}}, {"lk", {0,15,9}}, {"rw", {0,23,0}},
{"lb", {0,23,1}}, {"tw", {15,8,0}}, /*{"sq", {15,8,0}},*/ {"chr", {18,4,0}},
{"dl", {0,23,0}}, {"ctr", {0,22,0}}, {"nst", {0,21,0}}, {"lc", {0,22,0}},
{"sch", {16,4,0}}, {"ths", {0,1,20}}, {"nl", {0,21,0}}, {"lf", {0,15,6}},
{"ssn", {0,20,0}}, {"xt", {0,18,1}}, {"xp", {0,20,0}}, {"rst", {0,15,5}},
{"nh", {0,19,0}}, {"wr", {14,5,0}}
};
const int VowelsNumber = sizeof(Vowels)/sizeof(Sound);
const int ConsonantsNumber = sizeof(Consonants)/sizeof(Sound);
int VowelsRatesSum[3] = {0,0,0}, ConsonantsRatesSum[3] = {0,0,0};
int CountRateSum(Sound sounds[], const int num, const int part)
{
int sum = 0;
for(int i = 0; i < num; i++)
sum += sounds[i].rates[part];
return sum;
}
const char *GetLetters(int type, const int part)
{
Sound *sounds; int rate, i = 0;
if(type & 1)
sounds = Vowels, rate = rand() % VowelsRatesSum[part];
else
sounds = Consonants, rate = rand() % ConsonantsRatesSum[part];
do {
rate -= sounds[i++].rates[part];
} while(rate > 0);
return sounds[--i].chars;
}
static void CreateData() {
for(int i = 0; i < 3; i++) {
ConsonantsRatesSum[i] = CountRateSum(Consonants, ConsonantsNumber, i);
VowelsRatesSum[i] = CountRateSum(Vowels, VowelsNumber, i);
}
for( int i=0; i<N; ++i ) {
int type = rand();
Data[i] = GetLetters(type++, 0);
for( int j = 0; j < type%size_factor; ++j )
Data[i] += GetLetters(type++, 1);
Data[i] += GetLetters(type, 2);
}
MyString planet = Data[12]; planet[0] = toupper(planet[0]);
MyString helloworld = Data[0]; helloworld[0] = toupper(helloworld[0]);
helloworld += ", "+Data[1]+" "+Data[2]+" "+Data[3]+" "+Data[4]+" "+Data[5];
if ( !silent ) printf("Message from planet '%s': %s!\nAnalyzing whole text...\n", planet.c_str(), helloworld.c_str());
}
int main( int argc, char* argv[] ) {
try {
tbb::tick_count mainStartTime = tbb::tick_count::now();
srand(2);
//! Working threads count
// The 1st argument is the function to obtain 'auto' value; the 2nd is the default value
// The example interprets 0 threads as "run serially, then fully subscribed"
utility::thread_number_range threads(utility::get_default_num_threads,0);
utility::parse_cli_arguments(argc,argv,
utility::cli_argument_pack()
//"-h" option for displaying help is present implicitly
.positional_arg(threads,"n-of-threads",utility::thread_number_range_desc)
.positional_arg(N,"n-of-strings","number of strings")
.arg(verbose,"verbose","verbose mode")
.arg(silent,"silent","no output except elapsed time")
);
if ( silent ) verbose = false;
Data = new MyString[N];
CreateData();
if ( threads.first ) {
for(int p = threads.first; p <= threads.last; p = threads.step(p)) {
if ( !silent ) printf("threads = %d ", p );
global_control c(tbb::global_control::max_allowed_parallelism, p);
CountOccurrences( p );
}
} else { // Number of threads wasn't set explicitly. Run serial and parallel version
{ // serial run
if ( !silent ) printf("serial run ");
global_control c(tbb::global_control::max_allowed_parallelism, 1);
CountOccurrences(1);
}
{ // parallel run (number of threads is selected automatically)
if ( !silent ) printf("parallel run ");
global_control c(tbb::global_control::max_allowed_parallelism, utility::get_default_num_threads());
CountOccurrences(0);
}
}
delete[] Data;
utility::report_elapsed_time((tbb::tick_count::now() - mainStartTime).seconds());
return 0;
} catch(std::exception& e) {
std::cerr<<"error occurred. error text is :\"" <<e.what()<<"\"\n";
}
}

View File

@@ -0,0 +1,401 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks. Count_strings sample</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,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
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks.<br>Count_strings sample</h1>
</div>
<p>
The example counts the number of unique words in a text.
</p>
<div class="changes">
<div class="h3-alike">System Requirements</div>
<input type="checkbox">
<div class="show-hide">
<p>
For the most up to date system requirements, see the <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a>
</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Files</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="count_strings.cpp">count_strings.cpp</a>
<dd>Source code for the example.
<dt><a href="Makefile">Makefile</a>
<dd>Makefile for building the example.
</dl>
</div>
</div>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="msvs/">msvs</a>
<dd>Contains Microsoft* Visual Studio* workspace for building and running the example (Windows* systems only).
<dt><a href="xcode/">xcode</a>
<dd>Contains Xcode* IDE workspace for building and running the example (macOS* systems only).
</dl>
<p>For information about the minimum supported version of IDE, see <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a></p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Build instructions</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<p>
General build directions can be found <a href="../../index.html">here</a>.
</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Usage</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><tt>count_strings <i>-h</i></tt>
<dd>Prints the help for command line options
<dt><tt>count_strings [<i>n-of-threads</i>=value] [<i>n-of-strings</i>=value] [<i>verbose</i>] [<i>silent</i>]</tt>
<dt><tt>count_strings [<i>n-of-threads</i> [<i>n-of-strings</i>]] [<i>verbose</i>] [<i>silent</i>] </tt>
<dd><i>n-of-threads</i> is the number of threads to use; a range of the form <i>low</i>[:<i>high</i>], where low and optional high are non-negative integers or 'auto' for a platform-specific default number.<br>
<i>n-of-strings</i> is a number of strings.<br>
<i>verbose</i> - enables printing of extra information during execution.<br>
<i>silent</i> - no output except elapsed time.<br>
<dt>To run a short version of this example, e.g., for use with Intel&reg; Parallel Inspector:
<dd>Build a <i>debug</i> version of the example.
<br>Run it with a small number of strings and the desired number of threads, e.g., <tt>count_strings 2 10000</tt>.
</dl>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a>
<hr>
<div class="changes">
<div class="h3-alike">Legal Information</div>
<input type="checkbox">
<div class="show-hide">
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,310 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
A1F593A60B8F042A00073279 /* count_strings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1F593A50B8F042A00073279 /* count_strings.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
C3C5894B218B547B00DAC94C /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.intel.compilers.icc.latest;
fileType = sourcecode.cpp;
isEditable = 1;
outputFiles = (
);
script = "# Type a script or drag a script file from your workspace to insert its path.\n";
};
/* End PBXBuildRule section */
/* Begin PBXCopyFilesBuildPhase section */
8DD76F690486A84900D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 12;
dstPath = "";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
8DD76F6C0486A84900D96B5E /* count_strings */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = count_strings; sourceTree = BUILT_PRODUCTS_DIR; };
A1F593A50B8F042A00073279 /* count_strings.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = count_strings.cpp; path = ../count_strings.cpp; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8DD76F660486A84900D96B5E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
08FB7794FE84155DC02AAC07 /* count_strings */ = {
isa = PBXGroup;
children = (
08FB7795FE84155DC02AAC07 /* Source */,
1AB674ADFE9D54B511CA2CBB /* Products */,
);
name = count_strings;
sourceTree = "<group>";
};
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
A1F593A50B8F042A00073279 /* count_strings.cpp */,
);
name = Source;
sourceTree = "<group>";
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8DD76F6C0486A84900D96B5E /* count_strings */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8DD76F620486A84900D96B5E /* count_strings */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "count_strings" */;
buildPhases = (
8DD76F640486A84900D96B5E /* Sources */,
8DD76F660486A84900D96B5E /* Frameworks */,
8DD76F690486A84900D96B5E /* CopyFiles */,
);
buildRules = (
C3C5894B218B547B00DAC94C /* PBXBuildRule */,
);
dependencies = (
);
name = count_strings;
productInstallPath = "$(HOME)/bin";
productName = count_strings;
productReference = 8DD76F6C0486A84900D96B5E /* count_strings */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1000;
};
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "count_strings" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,
);
mainGroup = 08FB7794FE84155DC02AAC07 /* count_strings */;
projectDirPath = "";
projectRoot = "";
targets = (
8DD76F620486A84900D96B5E /* count_strings */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
8DD76F640486A84900D96B5E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A1F593A60B8F042A00073279 /* count_strings.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
A1F593C60B8F0E6E00073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = count_strings;
ZERO_LINK = NO;
};
name = Debug64;
};
A1F593C70B8F0E6E00073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = count_strings;
ZERO_LINK = NO;
};
name = Release64;
};
A1F593C80B8F0E6E00073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++11";
CLANG_CXX_LIBRARY = "libc++";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(TBBROOT)/include",
/opt/intel/tbb/include,
);
ICC_CXX_LANG_DIALECT = "c++11";
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
LIBRARY_SEARCH_PATHS = (
"$(TBBROOT)/lib",
/opt/intel/tbb/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
ONLY_ACTIVE_ARCH = YES;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-m64",
);
OTHER_LDFLAGS = (
"-m64",
"-ltbb_debug",
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Debug64;
};
A1F593C90B8F0E6E00073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++11";
CLANG_CXX_LIBRARY = "libc++";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(TBBROOT)/include",
/opt/intel/tbb/include,
);
ICC_CXX_LANG_DIALECT = "c++11";
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
LIBRARY_SEARCH_PATHS = (
"$(TBBROOT)/lib",
/opt/intel/tbb/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-m64",
);
OTHER_LDFLAGS = (
"-m64",
"-ltbb",
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Release64;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "count_strings" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F593C60B8F0E6E00073279 /* Debug64 */,
A1F593C70B8F0E6E00073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "count_strings" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F593C80B8F0E6E00073279 /* Debug64 */,
A1F593C90B8F0E6E00073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View File

@@ -0,0 +1,344 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks. Samples on concurrent_hash_map container</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,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
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks.<br>Samples on <code>concurrent_hash_map</code> container</h1>
</div>
<p>
This directory has examples of the <code>concurrent_hash_map</code> container.
</p>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="count_strings/readme.html">count_strings</a>
<dd>Concurrently inserts strings into a <code>concurrent_hash_map</code> container.
</dl>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a>
<hr>
<div class="changes">
<div class="h3-alike">Legal Information:</div>
<input type="checkbox">
<div class="show-hide">
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,344 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks. Samples on concurrent_priority_queue container</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,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
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks.<br>Samples on <code>concurrent_priority_queue</code> container</h1>
</div>
<p>
This directory has examples of the <code>concurrent_priority_queue</code> container.
</p>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="shortpath/readme.html">shortpath</a>
<dd>Solves the single source shortest path problem using a <code>concurrent_priority_queue</code> container.
</dl>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a>
<hr>
<div class="changes">
<div class="h3-alike">Legal Information:</div>
<input type="checkbox">
<div class="show-hide">
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,46 @@
# Copyright (c) 2005-2020 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.
# Common Makefile that builds and runs example.
# Just specify your program basename
PROG=shortpath
ARGS=4 N=1000 start=0 end=999 verbose
PERF_RUN_ARGS=auto N=1000 start=0 end=99 silent
# Trying to find if icl.exe is set
CXX1 = $(TBB_CXX)-
CXX2 = $(CXX1:icl.exe-=icl.exe)
CXX = $(CXX2:-=cl.exe)
# The C++ compiler options
MYCXXFLAGS = /TP /EHsc /W3 /nologo /D _CONSOLE /D _MBCS /D WIN32 /D _CRT_SECURE_NO_DEPRECATE $(CXXFLAGS)
MYLDFLAGS =/INCREMENTAL:NO /NOLOGO /DEBUG /FIXED:NO $(LDFLAGS)
all: release test
release:
$(CXX) *.cpp /MD /O2 /D NDEBUG $(MYCXXFLAGS) /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
debug:
$(CXX) *.cpp /MDd /Od /Zi /D TBB_USE_DEBUG /D _DEBUG $(MYCXXFLAGS) /link tbb_debug.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
clean:
@cmd.exe /C del $(PROG).exe *.obj *.?db *.manifest
test:
$(PROG) $(ARGS)
compiler_check:
@$(CXX) >nul 2>&1 || echo "$(CXX) command not found. Check if CXX=$(CXX) is set properly"
perf_build: release
perf_run:
$(PROG) $(PERF_RUN_ARGS)

View File

@@ -0,0 +1,427 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks. Shortpath sample</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,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
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks.<br>Shortpath sample</h1>
</div>
<p>
This directory contains a simple example that solves the single source
shortest path problem.
<br><br>
It is parameterized by N, a number of nodes, and a start and end node in [0..N).
A graph is generated with N nodes and some random number of connections between those nodes.
A parallel algorithm based on A* is used to find the shortest path.
<br><br>
This algorithm varies from serial A* in that it needs to add nodes back to
the open set when the g estimate (shortest path from start to the node) is improved,
even if the node has already been "visited". This is because nodes are added and removed
from the open-set in parallel, resulting in some less optimal paths being explored.
The open-set is implemented with the concurrent_priority_queue.
<br><br>
Note that since we re-visit nodes, the <i>f</i> estimate (on which the priority queue is sorted)
is not technically needed, so we could use this same parallel algorithm with just a concurrent_queue.
However, keeping the <i>f</i> estimate and using <code>concurrent_priority_queue</code>
results in much better performance.
<br><br>
Silent mode prints run time only,
regular mode prints the shortest path length,
and verbose mode prints out the shortest path.
<br><br>
The generated graph follows a pattern in which the closer two pairs of
node ids are together, the fewer hops there are in a typical path
between those nodes. So, for example, the path between 5 and 7 likely
has few hops whereas 14 to 78 has more and 0 to 9999 has even more,
etc.
</p>
<div class="changes">
<div class="h3-alike">System Requirements</div>
<input type="checkbox">
<div class="show-hide">
<p>
For the most up to date system requirements, see the <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a>
</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Files</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="shortpath.cpp">shortpath.cpp</a>
<dd>Driver.
<dt><a href="Makefile">Makefile</a>
<dd>Makefile for building the example.
</dl>
</div>
</div>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="msvs/">msvs</a>
<dd>Contains Microsoft* Visual Studio* workspace for building and running the example with the Intel&reg; C++ Compiler (Windows* systems only).
<dt><a href="xcode/">xcode</a>
<dd>Contains macOS* Xcode* workspace for building and running the example (macOS* systems only).
</dl>
<p>For information about the minimum supported version of IDE, see <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a></p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Build instructions</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<p>General build directions can be found <a href="../../index.html">here</a>.</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Usage</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><tt>shortpath <i>-h</i></tt>
<dd>Prints the help for command line options
<dt><tt>shortpath [<i>#threads</i>=value] [<i>verbose</i>] [<i>silent</i>] [<i>N</i>=value] [<i>start</i>=value] [<i>end</i>=value] [<i>#threads</i>]</tt>
<dd><tt><i>#threads</i></tt> is the number of threads to use; a range of the form <tt><i>low[:high]</i></tt> where <tt><i>low</i></tt> and optional <tt><i>high</i></tt> are non-negative integers, or <tt><i>'auto'</i></tt> for a platform-specific default number.<br>
<tt><i>verbose</i></tt> print full path to screen<br>
<tt><i>silent</i></tt> limits output to timing info; overrides verbose<br>
<tt><i>N</i></tt> number of nodes in graph<br>
<tt><i>start</i></tt> node to start path at<br>
<tt><i>end</i></tt> node to end path at<br>
<dt>To run a short version of this example, e.g., for use with Intel&reg; Parallel Inspector:
<dd>Build a <i>debug</i> version of the example
(see the <a href="../../index.html">build instructions</a>).
<br>Run it with a small problem size and the desired number of threads, e.g., <tt>shortpath&nbsp;4&nbsp;N=20&nbsp;start=0&nbsp;end=19</tt>.
</dl>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a>
<hr>
<div class="changes">
<div class="h3-alike">Legal Information</div>
<input type="checkbox">
<div class="show-hide">
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,359 @@
/*
Copyright (c) 2005-2020 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 <cstdio>
#include <vector>
#include <atomic>
#include <math.h>
#include "tbb/tick_count.h"
#include "tbb/task_group.h"
#include "tbb/concurrent_priority_queue.h"
#include "tbb/spin_mutex.h"
#include "tbb/parallel_for.h"
#include "tbb/blocked_range.h"
#include "tbb/global_control.h"
#include "../../common/utility/utility.h"
#include "../../common/utility/fast_random.h"
#include "../../common/utility/get_default_num_threads.h"
#if defined(_MSC_VER) && defined(_Wp64)
// Workaround for overzealous compiler warnings in /Wp64 mode
#pragma warning (disable: 4267)
#endif /* _MSC_VER && _Wp64 */
using namespace std;
using namespace tbb;
struct point {
double x, y;
point() {}
point(double _x, double _y) : x(_x), y(_y) {}
point(const point& p) : x(p.x), y(p.y) {}
};
double get_distance(const point& p1, const point& p2) {
double xdiff=p1.x-p2.x, ydiff=p1.y-p2.y;
return sqrt(xdiff*xdiff + ydiff*ydiff);
}
// generates random points on 2D plane within a box of maxsize width & height
point generate_random_point(utility::FastRandom& mr) {
const size_t maxsize=500;
double x = (double)(mr.get() % maxsize);
double y = (double)(mr.get() % maxsize);
return point(x,y);
}
// weighted toss makes closer nodes (in the point vector) heavily connected
bool die_toss(size_t a, size_t b, utility::FastRandom& mr) {
int node_diff = std::abs((int)(a-b));
// near nodes
if (node_diff < 16) return true;
// mid nodes
if (node_diff < 64) return ((int)mr.get() % 8 == 0);
// far nodes
if (node_diff < 512) return ((int)mr.get() % 16 == 0);
return false;
}
typedef vector<point> point_set;
typedef size_t vertex_id;
typedef std::pair<vertex_id,double> vertex_rec;
typedef vector<vector<vertex_id> > edge_set;
bool verbose = false; // prints bin details and other diagnostics to screen
bool silent = false; // suppress all output except for time
size_t N = 1000; // number of vertices
size_t src = 0; // start of path
size_t dst = N-1; // end of path
double INF=100000.0; // infinity
size_t grainsize = 16; // number of vertices per task on average
size_t max_spawn; // max tasks to spawn
std::atomic<size_t> num_spawn; // number of active tasks
point_set vertices; // vertices
edge_set edges; // edges
vector<vertex_id> predecessor; // for recreating path from src to dst
vector<double> f_distance; // estimated distances at particular vertex
vector<double> g_distance; // current shortest distances from src vertex
spin_mutex *locks; // a lock for each vertex
task_group *sp_group; // task group for tasks executing sub-problems
class compare_f {
public:
bool operator()(const vertex_rec& u, const vertex_rec& v) const {
return u.second>v.second;
}
};
concurrent_priority_queue<vertex_rec, compare_f> open_set; // tentative vertices
void shortpath_helper();
#if !__TBB_CPP11_LAMBDAS_PRESENT
class shortpath_helper_functor {
public:
shortpath_helper_functor() {};
void operator() () const { shortpath_helper(); }
};
#endif
void shortpath() {
sp_group = new task_group;
g_distance[src] = 0.0; // src's distance from src is zero
f_distance[src] = get_distance(vertices[src], vertices[dst]); // estimate distance from src to dst
open_set.push(make_pair(src,f_distance[src])); // push src into open_set
#if __TBB_CPP11_LAMBDAS_PRESENT
sp_group->run([](){ shortpath_helper(); });
#else
sp_group->run( shortpath_helper_functor() );
#endif
sp_group->wait();
delete sp_group;
}
void shortpath_helper() {
vertex_rec u_rec;
while (open_set.try_pop(u_rec)) {
vertex_id u = u_rec.first;
if (u==dst) continue;
double f = u_rec.second;
double old_g_u = 0.0;
{
spin_mutex::scoped_lock l(locks[u]);
if (f > f_distance[u]) continue; // prune search space
old_g_u = g_distance[u];
}
for (size_t i=0; i<edges[u].size(); ++i) {
vertex_id v = edges[u][i];
double new_g_v = old_g_u + get_distance(vertices[u], vertices[v]);
double new_f_v = 0.0;
// the push flag lets us move some work out of the critical section below
bool push = false;
{
spin_mutex::scoped_lock l(locks[v]);
if (new_g_v < g_distance[v]) {
predecessor[v] = u;
g_distance[v] = new_g_v;
new_f_v = f_distance[v] = g_distance[v] + get_distance(vertices[v], vertices[dst]);
push = true;
}
}
if (push) {
open_set.push(make_pair(v,new_f_v));
size_t n_spawn = ++num_spawn;
if (n_spawn < max_spawn) {
#if __TBB_CPP11_LAMBDAS_PRESENT
sp_group->run([]{ shortpath_helper(); });
#else
sp_group->run( shortpath_helper_functor() );
#endif
}
else --num_spawn;
}
}
}
--num_spawn;
}
void make_path(vertex_id src, vertex_id dst, vector<vertex_id>& path) {
vertex_id at = predecessor[dst];
if (at == N) path.push_back(src);
else if (at == src) { path.push_back(src); path.push_back(dst); }
else { make_path(src, at, path); path.push_back(dst); }
}
void print_path() {
vector<vertex_id> path;
double path_length=0.0;
make_path(src, dst, path);
if (verbose) printf("\n ");
for (size_t i=0; i<path.size(); ++i) {
if (path[i] != dst) {
double seg_length = get_distance(vertices[path[i]], vertices[path[i+1]]);
if (verbose) printf("%6.1f ", seg_length);
path_length += seg_length;
}
else if (verbose) printf("\n");
}
if (verbose) {
for (size_t i=0; i<path.size(); ++i) {
if (path[i] != dst) printf("(%4d)------>", (int)path[i]);
else printf("(%4d)\n", (int)path[i]);
}
}
if (verbose) printf("Total distance = %5.1f\n", path_length);
else if (!silent) printf(" %5.1f\n", path_length);
}
#if !__TBB_CPP11_LAMBDAS_PRESENT
class gen_vertices {
public:
gen_vertices() {}
void operator() (blocked_range<size_t>& r) const {
utility::FastRandom my_random((unsigned int)r.begin());
for (size_t i=r.begin(); i!=r.end(); ++i) {
vertices[i] = generate_random_point(my_random);
}
}
};
class gen_edges {
public:
gen_edges() {}
void operator() (blocked_range<size_t>& r) const {
utility::FastRandom my_random((unsigned int)r.begin());
for (size_t i=r.begin(); i!=r.end(); ++i) {
for (size_t j=0; j<i; ++j) {
if (die_toss(i, j, my_random))
edges[i].push_back(j);
}
}
}
};
class reset_vertices {
public:
reset_vertices() {}
void operator() (blocked_range<size_t>& r) const {
for (size_t i=r.begin(); i!=r.end(); ++i) {
f_distance[i] = g_distance[i] = INF;
predecessor[i] = N;
}
}
};
#endif
void InitializeGraph() {
global_control c(tbb::global_control::max_allowed_parallelism, utility::get_default_num_threads());
vertices.resize(N);
edges.resize(N);
predecessor.resize(N);
g_distance.resize(N);
f_distance.resize(N);
locks = new spin_mutex[N];
if (verbose) printf("Generating vertices...\n");
#if __TBB_CPP11_LAMBDAS_PRESENT
parallel_for(blocked_range<size_t>(0,N,64),
[&](blocked_range<size_t>& r) {
utility::FastRandom my_random(r.begin());
for (size_t i=r.begin(); i!=r.end(); ++i) {
vertices[i] = generate_random_point(my_random);
}
}, simple_partitioner());
#else
parallel_for(blocked_range<size_t>(0,N,64), gen_vertices(), simple_partitioner());
#endif
if (verbose) printf("Generating edges...\n");
#if __TBB_CPP11_LAMBDAS_PRESENT
parallel_for(blocked_range<size_t>(0,N,64),
[&](blocked_range<size_t>& r) {
utility::FastRandom my_random(r.begin());
for (size_t i=r.begin(); i!=r.end(); ++i) {
for (size_t j=0; j<i; ++j) {
if (die_toss(i, j, my_random))
edges[i].push_back(j);
}
}
}, simple_partitioner());
#else
parallel_for(blocked_range<size_t>(0,N,64), gen_edges(), simple_partitioner());
#endif
for (size_t i=0; i<N; ++i) {
for (size_t j=0; j<edges[i].size(); ++j) {
vertex_id k = edges[i][j];
edges[k].push_back(i);
}
}
if (verbose) printf("Done.\n");
}
void ReleaseGraph() {
delete []locks;
}
void ResetGraph() {
global_control c(tbb::global_control::max_allowed_parallelism, utility::get_default_num_threads());
#if __TBB_CPP11_LAMBDAS_PRESENT
parallel_for(blocked_range<size_t>(0,N),
[&](blocked_range<size_t>& r) {
for (size_t i=r.begin(); i!=r.end(); ++i) {
f_distance[i] = g_distance[i] = INF;
predecessor[i] = N;
}
});
#else
parallel_for(blocked_range<size_t>(0,N), reset_vertices());
#endif
}
int main(int argc, char *argv[]) {
try {
utility::thread_number_range threads(utility::get_default_num_threads);
utility::parse_cli_arguments(argc, argv,
utility::cli_argument_pack()
//"-h" option for displaying help is present implicitly
.positional_arg(threads,"#threads",utility::thread_number_range_desc)
.arg(verbose,"verbose"," print diagnostic output to screen")
.arg(silent,"silent"," limits output to timing info; overrides verbose")
.arg(N,"N"," number of vertices")
.arg(src,"start"," start of path")
.arg(dst,"end"," end of path")
);
if (silent) verbose = false; // make silent override verbose
else
printf("shortpath will run with %d vertices to find shortest path between vertices"
" %d and %d using %d:%d threads.\n",
(int)N, (int)src, (int)dst, (int)threads.first, (int)threads.last);
if (dst >= N) {
if (verbose)
printf("end value %d is invalid for %d vertices; correcting to %d\n", (int)dst, (int)N, (int)N-1);
dst = N-1;
}
num_spawn = 0;
max_spawn = N/grainsize;
tick_count t0, t1;
InitializeGraph();
for (int n_thr=threads.first; n_thr<=threads.last; n_thr=threads.step(n_thr)) {
ResetGraph();
global_control c(tbb::global_control::max_allowed_parallelism, n_thr);
t0 = tick_count::now();
shortpath();
t1 = tick_count::now();
if (!silent) {
if (predecessor[dst] != N) {
printf("%d threads: [%6.6f] The shortest path from vertex %d to vertex %d is:",
(int)n_thr, (t1-t0).seconds(), (int)src, (int)dst);
print_path();
}
else {
printf("%d threads: [%6.6f] There is no path from vertex %d to vertex %d\n",
(int)n_thr, (t1-t0).seconds(), (int)src, (int)dst);
}
} else
utility::report_elapsed_time((t1-t0).seconds());
}
ReleaseGraph();
return 0;
} catch(std::exception& e) {
cerr<<"error occurred. error text is :\"" <<e.what()<<"\"\n";
return 1;
}
}

View File

@@ -0,0 +1,310 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
61C4771B13CE199D0022F8F6 /* shortpath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61C4771A13CE199D0022F8F6 /* shortpath.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
C3C5894C218B560C00DAC94C /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.intel.compilers.icc.latest;
fileType = sourcecode.cpp;
isEditable = 1;
outputFiles = (
);
script = "# Type a script or drag a script file from your workspace to insert its path.\n";
};
/* End PBXBuildRule section */
/* Begin PBXCopyFilesBuildPhase section */
8DD76F690486A84900D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 12;
dstPath = "";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
61C4771A13CE199D0022F8F6 /* shortpath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = shortpath.cpp; path = ../shortpath.cpp; sourceTree = "<group>"; };
8DD76F6C0486A84900D96B5E /* Shortpath */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Shortpath; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8DD76F660486A84900D96B5E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
08FB7794FE84155DC02AAC07 /* Shortpath */ = {
isa = PBXGroup;
children = (
08FB7795FE84155DC02AAC07 /* Source */,
1AB674ADFE9D54B511CA2CBB /* Products */,
);
name = Shortpath;
sourceTree = "<group>";
};
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
61C4771A13CE199D0022F8F6 /* shortpath.cpp */,
);
name = Source;
sourceTree = "<group>";
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8DD76F6C0486A84900D96B5E /* Shortpath */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8DD76F620486A84900D96B5E /* Shortpath */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "Shortpath" */;
buildPhases = (
8DD76F640486A84900D96B5E /* Sources */,
8DD76F660486A84900D96B5E /* Frameworks */,
8DD76F690486A84900D96B5E /* CopyFiles */,
);
buildRules = (
C3C5894C218B560C00DAC94C /* PBXBuildRule */,
);
dependencies = (
);
name = Shortpath;
productInstallPath = "$(HOME)/bin";
productName = Shortpath;
productReference = 8DD76F6C0486A84900D96B5E /* Shortpath */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1000;
};
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "shortpath" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,
);
mainGroup = 08FB7794FE84155DC02AAC07 /* Shortpath */;
projectDirPath = "";
projectRoot = "";
targets = (
8DD76F620486A84900D96B5E /* Shortpath */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
8DD76F640486A84900D96B5E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
61C4771B13CE199D0022F8F6 /* shortpath.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
A1F593C60B8F0E6E00073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = Shortpath;
ZERO_LINK = NO;
};
name = Debug64;
};
A1F593C70B8F0E6E00073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = Shortpath;
ZERO_LINK = NO;
};
name = Release64;
};
A1F593C80B8F0E6E00073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(TBBROOT)/include",
/opt/intel/tbb/include,
);
ICC_CXX_LANG_DIALECT = "c++11";
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
LIBRARY_SEARCH_PATHS = (
"$(TBBROOT)/lib",
/opt/intel/tbb/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
ONLY_ACTIVE_ARCH = YES;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-m64",
);
OTHER_LDFLAGS = (
"-m64",
"-ltbb_debug",
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Debug64;
};
A1F593C90B8F0E6E00073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(TBBROOT)/include",
/opt/intel/tbb/include,
);
ICC_CXX_LANG_DIALECT = "c++11";
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
LIBRARY_SEARCH_PATHS = (
"$(TBBROOT)/lib",
/opt/intel/tbb/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-m64",
);
OTHER_LDFLAGS = (
"-m64",
"-ltbb",
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Release64;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "Shortpath" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F593C60B8F0E6E00073279 /* Debug64 */,
A1F593C70B8F0E6E00073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "shortpath" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F593C80B8F0E6E00073279 /* Debug64 */,
A1F593C90B8F0E6E00073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View File

@@ -0,0 +1,48 @@
# Copyright (c) 2005-2020 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.
# Common Makefile that builds and runs example.
# Just specify your program basename
PROG=binpack
ARGS= 4 N=1000
PERF_RUN_ARGS=auto N=1000 silent
# Trying to find if icl.exe is set
CXX1 = $(TBB_CXX)-
CXX2 = $(CXX1:icl.exe-=icl.exe)
CXX = $(CXX2:-=cl.exe)
# The C++ compiler options
MYCXXFLAGS = /TP /EHsc /W3 /nologo /D _CONSOLE /D _MBCS /D WIN32 /D _CRT_SECURE_NO_DEPRECATE $(CXXFLAGS)
MYLDFLAGS =/INCREMENTAL:NO /NOLOGO /DEBUG /FIXED:NO $(LDFLAGS)
all: release test
release:
$(CXX) *.cpp /MD /O2 /D NDEBUG $(MYCXXFLAGS) /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
debug:
$(CXX) *.cpp /MDd /Od /Zi /D TBB_USE_DEBUG /D _DEBUG $(MYCXXFLAGS) /link tbb_debug.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
profile:
$(CXX) *.cpp /MD /O2 /Zi /D NDEBUG $(MYCXXFLAGS) /D TBB_USE_THREADING_TOOLS /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
clean:
@cmd.exe /C del $(PROG).exe *.obj *.?db *.manifest
test:
$(PROG) $(ARGS)
compiler_check:
@$(CXX) >nul 2>&1 || echo "$(CXX) command not found. Check if CXX=$(CXX) is set properly"
perf_build: release
perf_run:
$(PROG) $(PERF_RUN_ARGS)

View File

@@ -0,0 +1,289 @@
/*
Copyright (c) 2005-2020 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.
*/
/* Bin-packing algorithm that attempts to use minimal number of bins B of
size V to contain N items of varying sizes. */
#include <string>
#include <iostream>
#include <cmath>
#include <vector>
#include <atomic>
#include "tbb/tick_count.h"
#include "tbb/flow_graph.h"
#include "tbb/global_control.h"
#include "../../common/utility/utility.h"
#include "../../common/utility/get_default_num_threads.h"
using tbb::tick_count;
using namespace tbb::flow;
typedef size_t size_type; // to represent non-zero indices, capacities, etc.
typedef size_t value_type; // the type of items we are attempting to pack into bins
typedef std::vector<value_type> bin; // we use a simple vector to represent a bin
// Our bin packers will be function nodes in the graph that take value_type items and
// return a dummy value. They will also implicitly send packed bins to the bin_buffer
// node, and unused items back to the value_pool node:
typedef multifunction_node<value_type, tuple<value_type, bin>, rejecting> bin_packer;
// Items are placed into a pool that all bin packers grab from, represent by a queue_node:
typedef queue_node<value_type> value_pool;
// Packed bins are placed in this buffer waiting to be serially printed and/or accounted for:
typedef buffer_node<bin> bin_buffer;
// Packed bins are taken from the_bin_buffer and processed by the_writer:
typedef function_node<bin, continue_msg, rejecting> bin_writer;
// Items are injected into the graph when this node sends them to the_value_pool:
typedef input_node<value_type> value_source;
// User-specified globals with default values
size_type V = 42; // desired capacity for each bin
size_type N = 1000; // number of elements to generate
bool verbose = false; // prints bin details and other diagnostics to screen
bool silent = false; // suppress all output except for time
int num_bin_packers=-1; // number of concurrent bin packers in operation; default is #threads;
// larger values can result in more bins at less than full capacity
size_type optimality=1; // 1 (default) is highest the algorithm can obtain; larger numbers run faster
// Calculated globals
size_type min_B; // lower bound on the optimal number of bins
size_type B; // the answer, i.e. number of bins used by the algorithm
size_type *input_array; // stores randomly generated input values
value_type item_sum; // sum of all randomly generated input values
std::atomic<value_type> packed_sum; // sum of all values currently packed into all bins
std::atomic<size_type> packed_items; // number of values currently packed into all bins
std::atomic<size_type> active_bins; // number of active bin_packers
bin_packer **bins; // the array of bin packers
// This class is the Body type for bin_packer
class bin_filler {
typedef bin_packer::output_ports_type ports_type;
bin my_bin; // the current bin that this bin_filler is packing
size_type my_used; // capacity of bin used by current contents (not to be confused with my_bin.size())
size_type relax, relax_val; // relaxation counter for determining when to settle for a non-full bin
bin_packer* my_bin_packer; // ptr to the bin packer that this body object is associated with
size_type bin_index; // index of the encapsulating bin packer in the global bins array
value_type looking_for; // the minimum size of item this bin_packer will accept
value_pool* the_value_pool; // the queue of incoming values
bool done; // flag to indicate that this binpacker has been deactivated
public:
bin_filler(size_t bidx, value_pool* _q) :
my_used(0), relax(0), relax_val(0), my_bin_packer(NULL), bin_index(bidx), looking_for(V), the_value_pool(_q), done(false) {}
void operator()(const value_type& item, ports_type& p) {
if (!my_bin_packer) my_bin_packer = bins[bin_index];
if (done) get<0>(p).try_put(item); // this bin_packer is done packing items; put item back to pool
else if (item > V) { // signal that packed_sum has reached item_sum at some point
size_type remaining = active_bins--;
if (remaining == 1 && packed_sum == item_sum) { // this is the last bin and it has seen everything
// this bin_packer may not have seen everything, so stay active
if (my_used>0) get<1>(p).try_put(my_bin);
my_bin.clear();
my_used = 0;
looking_for = V;
++active_bins;
}
else if (remaining == 1) { // this is the last bin, but there are remaining items
get<0>(p).try_put(V+1); // send out signal
++active_bins;
}
else if (remaining > 1) { // this is not the last bin; deactivate
if (my_used < V/(1+optimality*.1)) { // this bin is ill-utilized; throw back items and deactivate
packed_sum -= my_used;
packed_items -= my_bin.size();
for (size_type i=0; i<my_bin.size(); ++i)
get<0>(p).try_put(my_bin[i]);
the_value_pool->remove_successor(*my_bin_packer); // deactivate
done = true;
get<0>(p).try_put(V+1); // send out signal
}
else { // this bin is well-utilized; send out bin and deactivate
the_value_pool->remove_successor(*my_bin_packer); // build no more bins
done = true;
if (my_used>0) get<1>(p).try_put(my_bin);
get<0>(p).try_put(V+1); // send out signal
}
}
}
else if (item <= V-my_used && item >= looking_for) { // this item can be packed
my_bin.push_back(item);
my_used += item;
packed_sum += item;
++packed_items;
looking_for = V-my_used;
relax = 0;
if (packed_sum == item_sum) {
get<0>(p).try_put(V+1); // send out signal
}
if (my_used == V) {
get<1>(p).try_put(my_bin);
my_bin.clear();
my_used = 0;
looking_for = V;
}
}
else { // this item can't be packed; relax constraints
++relax;
if (relax >= (N-packed_items)/optimality) { // this bin_packer has looked through enough items
relax = 0;
--looking_for; // accept a wider range of items
if (looking_for == 0 && my_used < V/(1+optimality*.1) && my_used > 0 && active_bins > 1) {
// this bin_packer is ill-utilized and can't find items; deactivate and throw back items
size_type remaining = active_bins--;
if (remaining > 1) { // not the last bin_packer
the_value_pool->remove_successor(*my_bin_packer); // deactivate
done = true;
}
else active_bins++; // can't deactivate last bin_packer
packed_sum -= my_used;
packed_items -= my_bin.size();
for (size_type i=0; i<my_bin.size(); ++i)
get<0>(p).try_put(my_bin[i]);
my_bin.clear();
my_used = 0;
}
else if (looking_for == 0 && (my_used >= V/(1+optimality*.1) || active_bins == 1)) {
// this bin_packer can't find items but is well-utilized, so send it out and reset
get<1>(p).try_put(my_bin);
my_bin.clear();
my_used = 0;
looking_for = V;
}
}
get<0>(p).try_put(item); // put unused item back to pool
}
}
};
// source node uses this to send the values to the value_pool
class item_generator {
size_type counter;
public:
item_generator() : counter(0) {}
bool operator()(value_type& m) {
if (counter<N) {
m = input_array[counter];
++counter;
return true;
}
return false;
}
};
// the terminal function_node uses this to gather stats and print bin information
class bin_printer {
value_type running_count;
size_type item_count;
value_type my_min, my_max;
double avg;
public:
bin_printer() : running_count(0), item_count(0), my_min(V), my_max(0), avg(0) {}
continue_msg operator()(bin b) {
value_type sum=0;
++B;
if (verbose)
std::cout << "[ ";
for (size_type i=0; i<b.size(); ++i) {
if (verbose)
std::cout << b[i] << " ";
sum+=b[i];
++item_count;
}
if (sum < my_min) my_min = sum;
if (sum > my_max) my_max = sum;
avg += sum;
running_count += sum;
if (verbose)
std::cout << "]=" << sum << "; Done/Packed/Total cap: " << running_count << "/" << packed_sum << "/" << item_sum
<< " items:" << item_count << "/" << packed_items << "/" << N << " B=" << B << std::endl;
if (item_count == N) { // should be the last; print stats
avg = avg/(double)B;
if (!silent)
std::cout << "SUMMARY: #Bins used: " << B << "; Avg size: " << avg << "; Max size: " << my_max
<< "; Min size: " << my_min << "\n Lower bound on optimal #bins: " << min_B
<< "; Start #bins: " << num_bin_packers << std::endl;
}
return continue_msg(); // need to return something
}
};
int main(int argc, char *argv[]) {
try {
utility::thread_number_range threads(utility::get_default_num_threads);
utility::parse_cli_arguments(argc, argv,
utility::cli_argument_pack()
//"-h" option for displaying help is present implicitly
.positional_arg(threads,"#threads",utility::thread_number_range_desc)
.arg(verbose,"verbose"," print diagnostic output to screen")
.arg(silent,"silent"," limits output to timing info; overrides verbose")
.arg(N,"N"," number of values to pack")
.arg(V,"V"," capacity of each bin")
.arg(num_bin_packers,"#packers"," number of concurrent bin packers to use "
"(default=#threads)")
.arg(optimality,"optimality","controls optimality of solution; 1 is highest, use\n"
" larger numbers for less optimal but faster solution")
);
if (silent) verbose = false; // make silent override verbose
// Generate random input data
srand(42);
input_array = new value_type[N];
item_sum = 0;
for (size_type i=0; i<N; ++i) {
input_array[i] = rand() % V + 1; // generate items that fit in a bin
item_sum += input_array[i];
}
min_B = (item_sum % V) ? item_sum/V + 1 : item_sum/V;
tick_count start = tick_count::now();
for(int p = threads.first; p <= threads.last; p = threads.step(p)) {
tbb::global_control c(tbb::global_control::max_allowed_parallelism, p);
packed_sum = 0;
packed_items = 0;
B = 0;
if (num_bin_packers == -1) num_bin_packers = p;
active_bins = num_bin_packers;
if (!silent)
std::cout << "binpack running with " << item_sum << " capacity over " << N << " items, optimality="
<< optimality << ", " << num_bin_packers << " bins of capacity=" << V << " on " << p
<< " threads.\n";
graph g;
value_source the_source(g, item_generator());
value_pool the_value_pool(g);
make_edge(the_source, the_value_pool);
bin_buffer the_bin_buffer(g);
bins = new bin_packer*[num_bin_packers];
for (int i=0; i<num_bin_packers; ++i) {
bins[i] = new bin_packer(g, 1, bin_filler(i, &the_value_pool));
make_edge(the_value_pool, *(bins[i]));
make_edge(output_port<0>(*(bins[i])), the_value_pool);
make_edge(output_port<1>(*(bins[i])), the_bin_buffer);
}
bin_writer the_writer(g, 1, bin_printer());
make_edge(the_bin_buffer, the_writer);
the_source.activate();
g.wait_for_all();
for (int i=0; i<num_bin_packers; ++i) {
delete bins[i];
}
delete[] bins;
}
utility::report_elapsed_time((tick_count::now() - start).seconds());
delete[] input_array;
return 0;
} catch(std::exception& e) {
std::cerr<<"error occurred. error text is :\"" <<e.what()<<"\"\n";
return 1;
}
}

View File

@@ -0,0 +1,415 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks. Binpack sample</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,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
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks.<br>Binpack sample</h1>
</div>
<p>
This directory contains a simple tbb::flow example that performs
binpacking of N integer values into a near-optimal number of bins
of capacity V.
<br><br>
It features a source_node which passes randomly
generated integer values of size&lt;=V to a queue_node. Multiple
function_nodes set about taking values from this queue_node and
packing them into bins according to a best-fit policy. Items that
cannot be made to fit are rejected and returned to the queue. When
a bin is packed as well as it can be, it is passed to a buffer_node
where it waits to be picked up by another function_node. This final
function nodes gathers stats about the bin and optionally prints its
contents. When all bins are accounted for, it optionally prints a
summary of the quality of the bin-packing.
</p>
<div class="changes">
<div class="h3-alike">System Requirements</div>
<input type="checkbox">
<div class="show-hide">
<p>
For the most up to date system requirements, see the <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a>
</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Files</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="binpack.cpp">binpack.cpp</a>
<dd>Driver.
<dt><a href="Makefile">Makefile</a>
<dd>Makefile for building the example.
</dl>
</div>
</div>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="msvs/">msvs</a>
<dd>Contains Microsoft* Visual Studio* workspace for building and running the example with the Intel&reg; C++ Compiler (Windows* systems only).
<dt><a href="xcode/">xcode</a>
<dd>Contains Xcode* IDE workspace for building and running the example (macOS* systems only).
</dl>
<p>For information about the minimum supported version of IDE, see <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a></p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Build instructions</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<p>General build directions can be found <a href="../../index.html">here</a>.</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Usage</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><tt>binpack <i>-h</i></tt>
<dd>Prints the help for command line options
<dt><tt>binpack [<i>#threads</i>=value] [<i>verbose</i>] [<i>silent</i>] [<i>N</i>=value] [<i>V</i>=value] [<i>#packers</i>=value] [<i>optimality</i>=value] [<i>#threads</i>]</tt>
<dd><tt><i>#threads</i></tt> is the number of threads to use; a range of the form <i>low</i>[:<i>high</i>] where low and optional high are non-negative integers, or 'auto' for a platform-specific default number.<br>
<tt><i>verbose</i></tt> print diagnostic output to screen<br>
<tt><i>silent</i></tt> limits output to timing info; overrides verbose<br>
<tt><i>N</i></tt> number of values to pack<br>
<tt><i>V</i></tt> capacity of each bin<br>
<tt><i>#packers</i></tt> number of concurrent bin packers to use (default=#threads)<br>
<tt><i>optimality</i></tt> controls optimality of solution; 1 is highest, use larger numbers for less optimal but faster solution<br>
<dt>To run a short version of this example, e.g., for use with Intel&reg; Parallel Inspector:
<dd>Build a <i>debug</i> version of the example
(see the <a href="../../index.html">build instructions</a>).
<br>Run it with a small problem size and the desired number of threads, e.g., <tt>binpack&nbsp;4&nbsp;N=100</tt>.
</dl>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a>
<hr>
<div class="changes">
<div class="h3-alike">Legal Information</div>
<input type="checkbox">
<div class="show-hide">
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,310 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
A1F593A60B8F042A00073279 /* binpack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1F593A50B8F042A00073279 /* binpack.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
C3C58950218B599300DAC94C /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.intel.compilers.icc.latest;
fileType = sourcecode.cpp;
isEditable = 1;
outputFiles = (
);
script = "# Type a script or drag a script file from your workspace to insert its path.\n";
};
/* End PBXBuildRule section */
/* Begin PBXCopyFilesBuildPhase section */
8DD76F690486A84900D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 12;
dstPath = "";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
8DD76F6C0486A84900D96B5E /* Binpack */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Binpack; sourceTree = BUILT_PRODUCTS_DIR; };
A1F593A50B8F042A00073279 /* binpack.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = binpack.cpp; path = ../binpack.cpp; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8DD76F660486A84900D96B5E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
08FB7794FE84155DC02AAC07 /* Binpack */ = {
isa = PBXGroup;
children = (
08FB7795FE84155DC02AAC07 /* Source */,
1AB674ADFE9D54B511CA2CBB /* Products */,
);
name = Binpack;
sourceTree = "<group>";
};
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
A1F593A50B8F042A00073279 /* binpack.cpp */,
);
name = Source;
sourceTree = "<group>";
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8DD76F6C0486A84900D96B5E /* Binpack */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8DD76F620486A84900D96B5E /* Binpack */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "Binpack" */;
buildPhases = (
8DD76F640486A84900D96B5E /* Sources */,
8DD76F660486A84900D96B5E /* Frameworks */,
8DD76F690486A84900D96B5E /* CopyFiles */,
);
buildRules = (
C3C58950218B599300DAC94C /* PBXBuildRule */,
);
dependencies = (
);
name = Binpack;
productInstallPath = "$(HOME)/bin";
productName = Binpack;
productReference = 8DD76F6C0486A84900D96B5E /* Binpack */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1000;
};
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "binpack" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,
);
mainGroup = 08FB7794FE84155DC02AAC07 /* Binpack */;
projectDirPath = "";
projectRoot = "";
targets = (
8DD76F620486A84900D96B5E /* Binpack */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
8DD76F640486A84900D96B5E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A1F593A60B8F042A00073279 /* binpack.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
A1F593C60B8F0E6E00073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = Binpack;
ZERO_LINK = NO;
};
name = Debug64;
};
A1F593C70B8F0E6E00073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = Binpack;
ZERO_LINK = NO;
};
name = Release64;
};
A1F593C80B8F0E6E00073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(TBBROOT)/include",
/opt/intel/tbb/include,
);
ICC_CXX_LANG_DIALECT = "c++11";
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
LIBRARY_SEARCH_PATHS = (
"$(TBBROOT)/lib",
/opt/intel/tbb/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
ONLY_ACTIVE_ARCH = YES;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-m64",
);
OTHER_LDFLAGS = (
"-m64",
"-ltbb_debug",
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Debug64;
};
A1F593C90B8F0E6E00073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(TBBROOT)/include",
/opt/intel/tbb/include,
);
ICC_CXX_LANG_DIALECT = "c++11";
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
LIBRARY_SEARCH_PATHS = (
"$(TBBROOT)/lib",
/opt/intel/tbb/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-m64",
);
OTHER_LDFLAGS = (
"-m64",
"-ltbb",
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Release64;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "Binpack" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F593C60B8F0E6E00073279 /* Debug64 */,
A1F593C70B8F0E6E00073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "binpack" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F593C80B8F0E6E00073279 /* Debug64 */,
A1F593C90B8F0E6E00073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View File

@@ -0,0 +1,48 @@
# Copyright (c) 2005-2020 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.
# Common Makefile that builds and runs example.
# Just specify your program basename
PROG=Cholesky
ARGS=4 2
# Trying to find if icl.exe is set
CXX1 = $(TBB_CXX)-
CXX2 = $(CXX1:icl.exe-=icl.exe)
CXX = $(CXX2:-=cl.exe)
# The C++ compiler options
MYCXXFLAGS = /TP /EHsc /W3 /nologo /D _CONSOLE /D _MBCS /D WIN32 /D _WIN32_WINNT=0x0501 $(CXXFLAGS)
MYLDFLAGS = /INCREMENTAL:NO /NOLOGO /DEBUG /FIXED:NO $(LDFLAGS)
# MKL support
MKL_LIBS1 = $(TBB_TARGET_ARCH)
MKL_LIBS2 = $(MKL_LIBS1:ia32=mkl_core.lib mkl_sequential.lib mkl_intel_c.lib)
MKL_LIBS = $(MKL_LIBS2:intel64=mkl_core.lib mkl_sequential.lib mkl_intel_lp64.lib)
all: release test
release: compiler_check
$(CXX) *.cpp /MD /O2 /D NDEBUG $(MYCXXFLAGS) /link tbb.lib $(MKL_LIBS) $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
debug: compiler_check
$(CXX) *.cpp /MDd /Od /Zi /D TBB_USE_DEBUG /D _DEBUG $(MYCXXFLAGS) /link tbb_debug.lib $(MKL_LIBS) $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
profile: compiler_check
$(CXX) *.cpp /MD /O2 /Zi /D NDEBUG $(MYCXXFLAGS) /D TBB_USE_THREADING_TOOLS /link tbb.lib $(MKL_LIBS) $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
clean:
@cmd.exe /C del $(PROG).exe *.obj *.?db *.manifest
test:
$(PROG) $(ARGS)
compiler_check:
@echo compiler_test>compiler_test && @$(CXX) /E compiler_test >nul 2>&1 || echo "$(CXX) command not found. Check if CXX=$(CXX) is set properly"
@cmd.exe /C del compiler_test

View File

@@ -0,0 +1,713 @@
/*
Copyright (c) 2005-2020 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 <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include "mkl_lapack.h"
#include "mkl.h"
#include "tbb/tbb_config.h"
#include "tbb/flow_graph.h"
#include "tbb/tick_count.h"
#include "tbb/global_control.h"
// Application command line arguments parsing
#include "../../common/utility/utility.h"
#include "../../common/utility/get_default_num_threads.h"
/************************************************************
FORWARD DECLARATIONS
************************************************************/
/**********************************************
Read or generate a positive-definite matrix
-- reads from file if fname != NULL
-- sets n to matrix size
-- allocates and reads values in to A
-- otherwise generates a matrix
-- uses n to determine size
-- allocates and generates values in to A
**********************************************/
void matrix_init( double * &A, int &n, const char *fname );
/**********************************************
Writes a lower triangular matrix to a file
-- first line of file is n
-- subsequently 1 row per line
**********************************************/
void matrix_write ( double *A, int n, const char *fname, bool is_triangular = false );
/************************************************************
GLOBAL VARIABLES
************************************************************/
bool g_benchmark_run = false;
int g_n = -1, g_b = -1, g_num_trials = 1;
char *g_input_file_name = NULL;
char *g_output_prefix = NULL;
std::string g_alg_name;
int g_num_tbb_threads;
// Creates tiled array
static double ***create_tile_array( double *A, int n, int b ) {
const int p = n/b;
double ***tile = (double ***)calloc( sizeof( double ** ), p );
for ( int j = 0; j < p; ++j ) {
tile[j] = (double **)calloc( sizeof( double * ), p );
}
for ( int j = 0; j < p; ++j ) {
for ( int i = 0; i < p; ++i ) {
double *temp_block = (double *)calloc( sizeof( double ), b*b );
for ( int A_j = j*b, T_j = 0; T_j < b; ++A_j, ++T_j ) {
for ( int A_i = i*b, T_i = 0; T_i < b; ++A_i, ++T_i ) {
temp_block[T_j*b+T_i] = A[A_j*n+A_i];
}
}
tile[j][i] = temp_block;
}
}
return tile;
}
static void collapse_tile_array( double ***tile, double *A, int n, int b ) {
const int p = n/b;
for ( int j = 0; j < p; ++j ) {
for ( int i = 0; i < p; ++i ) {
double *temp_block = tile[j][i];
for ( int A_j = j*b, T_j = 0; T_j < b; ++A_j, ++T_j ) {
for ( int A_i = i*b, T_i = 0; T_i < b; ++A_i, ++T_i ) {
A[A_j*n+A_i] = temp_block[T_j*b+T_i];
}
}
free( temp_block );
tile[j][i] = NULL;
}
free( tile[j] );
}
free( tile );
}
/************************************************************
Helper base class: algorithm
************************************************************/
class algorithm {
std::string name;
bool is_tiled;
bool check_if_valid( double *A0, double *C, double *A, int n ) {
char transa = 'n', transb = 't';
double alpha = 1;
double beta = 0;
for ( int i = 0; i < n; ++i ) {
for ( int j = i+1; j < n; ++j ) {
A0[j*n+i] = 0.;
}
}
dgemm ( &transa, &transb, &n, &n, &n, &alpha, A0, &n, A0, &n, &beta, C, &n );
for ( int j = 0; j < n; ++j ) {
for ( int i = 0; i < n; ++i ) {
const double epsilon = std::abs( A[j*n+i]*0.1 );
if ( std::abs( C[j*n+i] - A[j*n+i] ) > epsilon ) {
printf( "ERROR: %s did not validate at C(%d,%d) = %lf != A(%d,%d) = %lf\n",
name.c_str(), i, j, C[j*n+i], i, j, A[j*n+i] );
printf( "ERROR: %g; %g < %g < %g\n", epsilon, A[j*n+i] - epsilon, C[j*n+i], A[j*n+i] + epsilon );
return false;
}
}
}
return true;
}
public:
algorithm( const std::string& alg_name, bool t ) : name(alg_name), is_tiled(t) {}
double operator() ( double *A, int n, int b, int trials ) {
tbb::tick_count t0, t1;
double elapsed_time = 0.0;
double *A0 = (double *)calloc( sizeof( double ), n*n );
double *C = (double *)calloc( sizeof( double ), n*n );
for ( int t = 0; t < trials+1; ++t ) {
if ( is_tiled ) {
double ***tile = create_tile_array( A, n, b );
t0 = tbb::tick_count::now();
func( tile, n, b );
t1 = tbb::tick_count::now();
collapse_tile_array( tile, A0, n, b );
}
else {
memcpy( A0, A, sizeof( double )*n*n );
t0 = tbb::tick_count::now();
func( A0, n, b );
t1 = tbb::tick_count::now();
}
if ( t ) elapsed_time += (t1-t0).seconds();
if( !g_benchmark_run && !check_if_valid( A0, C, A, n ) ) {
if ( g_output_prefix ) {
std::string s( g_output_prefix );
s += "_" + name + ".txt";
matrix_write( A0, g_n, s.c_str(), true );
free( A0 );
free( C );
return 0.;
}
}
}
if ( g_output_prefix ) {
std::string s( g_output_prefix );
s += "_" + name + ".txt";
matrix_write( A0, g_n, s.c_str(), true );
}
printf( "%s %d %d %d %d %lf %lf\n", name.c_str(), g_num_tbb_threads, trials, n, b, elapsed_time, elapsed_time/trials );
free( A0 );
free( C );
return elapsed_time;
}
protected:
// Main algorithm body function must be defined in any direved class
virtual void func( void * ptr, int n, int b ) = 0;
};
/***********************************************************/
static void call_dpotf2( double ***tile, int b, int k ) {
double *A_block = tile[k][k];
char uplo = 'l';
int info = 0;
dpotf2( &uplo, &b, A_block, &b, &info );
return;
}
static void call_dtrsm( double ***tile, int b, int k, int j ) {
double *A_block = tile[k][j];
double *L_block = tile[k][k];
char uplo = 'l', side = 'r', transa = 't', diag = 'n';
double alpha = 1;
dtrsm( &side, &uplo, &transa, &diag, &b, &b, &alpha, L_block, &b, A_block, &b );
return;
}
static void call_dsyr2k( double ***tile, int b, int k, int j, int i ) {
double *A_block = tile[i][j];
char transa = 'n', transb = 't';
char uplo = 'l';
double alpha = -1;
double beta = 1;
if ( i == j ) { // Diagonal block
double *L_block = tile[k][i];
dsyrk( &uplo, &transa, &b, &b, &alpha, L_block, &b, &beta, A_block, &b );
} else { // Non-diagonal block
double *L2_block = tile[k][i];
double *L1_block = tile[k][j];
dgemm( &transa, &transb, &b, &b, &b, &alpha, L1_block, &b, L2_block, &b, &beta, A_block, &b );
}
return;
}
class algorithm_crout : public algorithm
{
public:
algorithm_crout() : algorithm("crout_cholesky", true) {}
protected:
virtual void func( void * ptr, int n, int b ) {
double ***tile = (double ***)ptr;
const int p = n/b;
for ( int k = 0; k < p; ++k ) {
call_dpotf2( tile, b, k );
for ( int j = k+1; j < p; ++j ) {
call_dtrsm( tile, b, k, j );
for ( int i = k+1; i <= j; ++i ) {
call_dsyr2k( tile, b, k, j, i );
}
}
}
}
};
class algorithm_dpotrf : public algorithm
{
public:
algorithm_dpotrf() : algorithm("dpotrf_cholesky", false) {}
protected:
virtual void func( void * ptr, int n, int /* b */ ) {
double *A = (double *)ptr;
int lda = n;
int info = 0;
char uplo = 'l';
dpotrf( &uplo, &n, A, &lda, &info );
}
};
/************************************************************
Begin data join graph based version of cholesky
************************************************************/
typedef union {
char a[4];
size_t tag;
} tag_t;
typedef double * tile_t;
typedef std::pair< tag_t, tile_t > tagged_tile_t;
typedef tbb::flow::tuple< tagged_tile_t > t1_t;
typedef tbb::flow::tuple< tagged_tile_t, tagged_tile_t > t2_t;
typedef tbb::flow::tuple< tagged_tile_t, tagged_tile_t, tagged_tile_t > t3_t;
typedef tbb::flow::multifunction_node< tagged_tile_t, t1_t > dpotf2_node_t;
typedef tbb::flow::multifunction_node< t2_t, t2_t > dtrsm_node_t;
typedef tbb::flow::multifunction_node< t3_t, t3_t > dsyr2k_node_t;
typedef tbb::flow::join_node< t2_t, tbb::flow::tag_matching > dtrsm_join_t;
typedef tbb::flow::join_node< t3_t, tbb::flow::tag_matching > dsyr2k_join_t;
class dpotf2_body {
int p;
int b;
public:
dpotf2_body( int p_, int b_ ) : p(p_), b(b_) {}
void operator()( const tagged_tile_t &in, dpotf2_node_t::output_ports_type &ports ) {
int k = in.first.a[0];
tile_t A_block = in.second;
tag_t t;
t.tag = 0;
t.a[0] = k;
char uplo = 'l';
int info = 0;
dpotf2( &uplo, &b, A_block, &b, &info );
// Send to dtrsms in same column
// k == k j == k
t.a[2] = k;
for ( int j = k+1; j < p; ++j ) {
t.a[1] = j;
tbb::flow::get<0>( ports ).try_put( std::make_pair( t, A_block ) );
}
}
};
class dtrsm_body {
int p;
int b;
public:
dtrsm_body( int p_, int b_ ) : p(p_), b(b_) {}
void operator()( const t2_t &in, dtrsm_node_t::output_ports_type &ports ) {
using tbb::flow::get;
tagged_tile_t in0 = get<0>( in );
tagged_tile_t in1 = get<1>( in );
int k = in0.first.a[0];
int j = in0.first.a[1];
tile_t L_block = in0.second;
tile_t A_block = in1.second;
tag_t t;
t.tag = 0;
t.a[0] = k;
char uplo = 'l', side = 'r', transa = 't', diag = 'n';
double alpha = 1;
dtrsm( &side, &uplo, &transa, &diag, &b, &b, &alpha, L_block, &b, A_block, &b);
// Send to rest of my row
t.a[1] = j;
for ( int i = k+1; i <= j; ++i ) {
t.a[2] = i;
get<0>( ports ).try_put( std::make_pair( t, A_block ) );
}
// Send to transposed row
t.a[2] = j;
for ( int i = j; i < p; ++i ) {
t.a[1] = i;
get<1>( ports ).try_put( std::make_pair( t, A_block ) );
}
}
};
class dsyr2k_body {
int p;
int b;
public:
dsyr2k_body( int p_, int b_ ) : p(p_), b(b_) {}
void operator()( const t3_t &in, dsyr2k_node_t::output_ports_type &ports ) {
using tbb::flow::get;
tag_t t;
t.tag = 0;
char transa = 'n', transb = 't';
char uplo = 'l';
double alpha = -1;
double beta = 1;
tagged_tile_t in0 = get<0>( in );
tagged_tile_t in1 = get<1>( in );
tagged_tile_t in2 = get<2>( in );
int k = in2.first.a[0];
int j = in2.first.a[1];
int i = in2.first.a[2];
tile_t A_block = in2.second;
if ( i == j ) { // Diagonal block
tile_t L_block = in0.second;
dsyrk( &uplo, &transa, &b, &b, &alpha, L_block, &b, &beta, A_block, &b );
} else { // Non-diagonal block
tile_t L1_block = in0.second;
tile_t L2_block = in1.second;
dgemm( &transa, &transb, &b, &b, &b, &alpha, L1_block, &b, L2_block, &b, &beta, A_block, &b );
}
// All outputs flow to next step
t.a[0] = k+1;
t.a[1] = j;
t.a[2] = i;
if ( k != p-1 && j == k+1 && i == k+1 ) {
get<0>( ports ).try_put( std::make_pair( t, A_block ) );
}
if ( k < p-2 ) {
if ( i == k+1 && j > i ) {
t.a[0] = k+1;
t.a[1] = j;
get<1>( ports ).try_put( std::make_pair( t, A_block ) );
}
if ( j != k+1 && i != k+1 ) {
t.a[0] = k+1;
t.a[1] = j;
t.a[2] = i;
get<2>( ports ).try_put( std::make_pair( t, A_block ) );
}
}
}
};
struct tagged_tile_to_size_t {
size_t operator()( const tagged_tile_t &t ) {
return t.first.tag;
}
};
class algorithm_join : public algorithm
{
public:
algorithm_join() : algorithm("data_join_cholesky", true) {}
protected:
virtual void func( void * ptr, int n, int b ) {
using tbb::flow::unlimited;
using tbb::flow::output_port;
using tbb::flow::input_port;
double ***tile = (double ***)ptr;
const int p = n/b;
tbb::flow::graph g;
dpotf2_node_t dpotf2_node( g, unlimited, dpotf2_body(p, b) );
dtrsm_node_t dtrsm_node( g, unlimited, dtrsm_body(p, b) );
dsyr2k_node_t dsyr2k_node( g, unlimited, dsyr2k_body(p, b) );
dtrsm_join_t dtrsm_join( g, tagged_tile_to_size_t(), tagged_tile_to_size_t() );
dsyr2k_join_t dsyr2k_join( g, tagged_tile_to_size_t(), tagged_tile_to_size_t(), tagged_tile_to_size_t() );
make_edge( output_port<0>( dsyr2k_node ), dpotf2_node );
make_edge( output_port<0>( dpotf2_node ), input_port<0>( dtrsm_join ) );
make_edge( output_port<1>( dsyr2k_node ), input_port<1>( dtrsm_join ) );
make_edge( dtrsm_join, dtrsm_node );
make_edge( output_port<0>( dtrsm_node ), input_port<0>( dsyr2k_join ) );
make_edge( output_port<1>( dtrsm_node ), input_port<1>( dsyr2k_join ) );
make_edge( output_port<2>( dsyr2k_node ), input_port<2>( dsyr2k_join ) );
make_edge( dsyr2k_join, dsyr2k_node );
// Now we need to send out the tiles to their first nodes
tag_t t;
t.tag = 0;
t.a[0] = 0;
t.a[1] = 0;
t.a[2] = 0;
// Send to feedback input of first dpotf2
// k == 0, j == 0, i == 0
dpotf2_node.try_put( std::make_pair( t, tile[0][0] ) );
// Send to feedback input (port 1) of each dtrsm
// k == 0, j == 1..p-1
for ( int j = 1; j < p; ++j ) {
t.a[1] = j;
input_port<1>( dtrsm_join ).try_put( std::make_pair( t, tile[0][j] ) );
}
// Send to feedback input (port 2) of each dsyr2k
// k == 0
for ( int i = 1; i < p; ++i ) {
t.a[2] = i;
for ( int j = i; j < p; ++j ) {
t.a[1] = j;
input_port<2>( dsyr2k_join ).try_put( std::make_pair( t, tile[i][j] ) );
}
}
g.wait_for_all();
}
};
/************************************************************
End data join graph based version of cholesky
************************************************************/
/************************************************************
Begin dependence graph based version of cholesky
************************************************************/
typedef tbb::flow::continue_node< tbb::flow::continue_msg > continue_type;
typedef continue_type * continue_ptr_type;
#if !__TBB_CPP11_LAMBDAS_PRESENT
// Using helper functor classes (instead of built-in C++ 11 lambda functions)
class call_dpotf2_functor
{
double ***tile;
int b, k;
public:
call_dpotf2_functor( double ***tile_, int b_, int k_ )
: tile(tile_), b(b_), k(k_) {}
void operator()( const tbb::flow::continue_msg & ) { call_dpotf2( tile, b, k ); }
};
class call_dtrsm_functor
{
double ***tile;
int b, k, j;
public:
call_dtrsm_functor( double ***tile_, int b_, int k_, int j_ )
: tile(tile_), b(b_), k(k_), j(j_) {}
void operator()( const tbb::flow::continue_msg & ) { call_dtrsm( tile, b, k, j ); }
};
class call_dsyr2k_functor
{
double ***tile;
int b, k, j, i;
public:
call_dsyr2k_functor( double ***tile_, int b_, int k_, int j_, int i_ )
: tile(tile_), b(b_), k(k_), j(j_), i(i_) {}
void operator()( const tbb::flow::continue_msg & ) { call_dsyr2k( tile, b, k, j, i ); }
};
#endif // !__TBB_CPP11_LAMBDAS_PRESENT
class algorithm_depend : public algorithm
{
public:
algorithm_depend() : algorithm("depend_cholesky", true) {}
protected:
virtual void func( void * ptr, int n, int b ) {
double ***tile = (double ***)ptr;
const int p = n/b;
continue_ptr_type *c = new continue_ptr_type[p];
continue_ptr_type **t = new continue_ptr_type *[p];
continue_ptr_type ***u = new continue_ptr_type **[p];
tbb::flow::graph g;
for ( int k = p-1; k >= 0; --k ) {
c[k] = new continue_type( g,
#if __TBB_CPP11_LAMBDAS_PRESENT
[=]( const tbb::flow::continue_msg & ) { call_dpotf2( tile, b, k ); } );
#else
call_dpotf2_functor( tile, b, k ) );
#endif // __TBB_CPP11_LAMBDAS_PRESENT
t[k] = new continue_ptr_type[p];
u[k] = new continue_ptr_type *[p];
for ( int j = k+1; j < p; ++j ) {
t[k][j] = new continue_type( g,
#if __TBB_CPP11_LAMBDAS_PRESENT
[=]( const tbb::flow::continue_msg & ) { call_dtrsm( tile, b, k, j ); } );
#else
call_dtrsm_functor( tile, b, k, j ) );
#endif // __TBB_CPP11_LAMBDAS_PRESENT
make_edge( *c[k], *t[k][j] );
u[k][j] = new continue_ptr_type[p];
for ( int i = k+1; i <= j; ++i ) {
u[k][j][i] = new continue_type( g,
#if __TBB_CPP11_LAMBDAS_PRESENT
[=]( const tbb::flow::continue_msg & ) { call_dsyr2k( tile, b, k, j, i ); } );
#else
call_dsyr2k_functor( tile, b, k, j, i ) );
#endif // __TBB_CPP11_LAMBDAS_PRESENT
if ( k < p-2 && k+1 != j && k+1 != i ) {
make_edge( *u[k][j][i], *u[k+1][j][i] );
}
make_edge( *t[k][j], *u[k][j][i] );
if ( i != j ) {
make_edge( *t[k][i], *u[k][j][i] );
}
if ( k < p-2 && j > i && i == k+1 ) {
make_edge( *u[k][j][i], *t[i][j] );
}
}
}
if ( k != p-1 ) {
make_edge( *u[k][k+1][k+1], *c[k+1] );
}
}
c[0]->try_put( tbb::flow::continue_msg() );
g.wait_for_all();
}
}; // class algorithm_depend
/************************************************************
End dependence graph based version of cholesky
************************************************************/
bool process_args( int argc, char *argv[] ) {
utility::parse_cli_arguments( argc, argv,
utility::cli_argument_pack()
//"-h" option for displaying help is present implicitly
.positional_arg( g_n, "size", "the row/column size of NxN matrix (size <= 46000)" )
.positional_arg( g_b, "blocksize", "the block size; size must be a multiple of the blocksize" )
.positional_arg( g_num_trials, "num_trials", "the number of times to run each algorithm" )
.positional_arg( g_output_prefix, "output_prefix",
"if provided the prefix will be preappended to output files:\n"
" output_prefix_posdef.txt\n"
" output_prefix_X.txt; where X is the algorithm used\n"
" if output_prefix is not provided, no output will be written" )
.positional_arg( g_alg_name, "algorithm", "name of the used algorithm - can be dpotrf, crout, depend or join" )
.positional_arg( g_num_tbb_threads, "num_tbb_threads", "number of started TBB threads" )
.arg( g_input_file_name, "input_file", "if provided it will be read to get the input matrix" )
.arg( g_benchmark_run, "-x", "skips all validation" )
);
if ( g_n > 46000 ) {
printf( "ERROR: invalid 'size' value (must be less or equal 46000): %d\n", g_n );
return false;
}
if ( g_n%g_b != 0 ) {
printf( "ERROR: size %d must be a multiple of the blocksize %d\n", g_n, g_b );
return false;
}
if ( g_n/g_b > 256 ) {
// Because tile index size is 1 byte only in tag_t type
printf( "ERROR: size / blocksize must be less or equal 256, but %d / %d = %d\n", g_n, g_b, g_n/g_b );
return false;
}
if ( g_b == -1 || (g_n == -1 && g_input_file_name == NULL) ) {
return false;
}
return true;
}
int main(int argc, char *argv[]) {
g_num_tbb_threads = utility::get_default_num_threads();
typedef std::map< std::string, algorithm * > algmap_t;
algmap_t algmap;
// Init algorithms
algmap.insert(std::pair<std::string, algorithm *>("dpotrf", new algorithm_dpotrf));
algmap.insert(std::pair<std::string, algorithm *>("crout", new algorithm_crout));
algmap.insert(std::pair<std::string, algorithm *>("depend", new algorithm_depend));
algmap.insert(std::pair<std::string, algorithm *>("join", new algorithm_join));
if ( !process_args( argc, argv ) ) {
printf( "ERROR: Invalid arguments. Run: %s -h\n", argv[0] );
exit( 1 );
}
tbb::global_control c(tbb::global_control::max_allowed_parallelism, g_num_tbb_threads);
double *A = NULL;
// Read input matrix
matrix_init( A, g_n, g_input_file_name );
// Write input matrix if output_prefix is set and we didn't read from a file
if ( !g_input_file_name && g_output_prefix ) {
std::string s( g_output_prefix );
s += "_posdef.txt";
matrix_write( A, g_n, s.c_str() );
}
if ( g_alg_name.empty() ) {
for ( algmap_t::iterator i = algmap.begin(); i != algmap.end(); ++i ) {
algorithm* const alg = i->second;
(*alg)( A, g_n, g_b, g_num_trials );
}
}
else {
algmap_t::iterator alg_iter = algmap.find(g_alg_name);
if ( alg_iter != algmap.end() ) {
algorithm* const alg = alg_iter->second;
(*alg)( A, g_n, g_b, g_num_trials );
}
else {
printf( "ERROR: Invalid algorithm name: %s\n", g_alg_name.c_str() );
exit( 2 );
}
}
free( A );
return 0;
}

View File

@@ -0,0 +1,134 @@
/*
Copyright (c) 2005-2020 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 <cstdio>
#include <cassert>
#include <cstring>
#include <cstdlib>
#include <mkl_cblas.h>
static void posdef_gen( double * A, int n )
{
/* Allocate memory for the matrix and its transpose */
double *L = (double *)calloc( sizeof( double ), n*n );
assert( L );
double *LT = (double *)calloc( sizeof( double ), n*n) ;
assert( LT );
memset( A, 0, sizeof( double )*n*n );
/* Generate a conditioned matrix and fill it with random numbers */
for ( int j = 0; j < n; ++j ) {
for ( int k = 0; k < j; ++k ) {
// The initial value has to be between [0,1].
L[k*n+j] = ( ( (j*k) / ((double)(j+1)) / ((double)(k+2)) * 2.0) - 1.0 ) / ((double)n);
}
L[j*n+j] = 1;
}
/* Compute transpose of the matrix */
for ( int i = 0; i < n; ++i ) {
for ( int j = 0; j < n; ++j ) {
LT[j*n+i] = L[i*n+j];
}
}
cblas_dgemm( CblasColMajor, CblasNoTrans, CblasNoTrans, n, n, n, 1, L, n, LT, n, 0, A, n );
free( L );
free( LT );
}
// Read the matrix from the input file
void matrix_init( double * &A, int &n, const char *fname ) {
if( fname ) {
int i;
int j;
FILE *fp;
fp = fopen( fname, "r" );
if ( fp == NULL ) {
fprintf( stderr, "\nFile does not exist\n" );
exit( 0 );
}
if ( fscanf( fp, "%d", &n ) <= 0 ) {
fprintf( stderr,"\nCouldn't read n from %s\n", fname );
exit( 1 );
}
A = (double *)calloc( sizeof( double ), n*n );
for ( i = 0; i < n; ++i ) {
for ( j = 0; j <= i; ++j ) {
if( fscanf( fp, "%lf ", &A[i*n+j] ) <= 0) {
fprintf( stderr,"\nMatrix size incorrect %i %i\n", i, j );
exit( 1 );
}
if ( i != j ) {
A[j*n+i] = A[i*n+j];
}
}
}
fclose( fp );
} else {
A = (double *)calloc( sizeof( double ), n*n );
posdef_gen( A, n );
}
}
// write matrix to file
void matrix_write ( double *A, int n, const char *fname, bool is_triangular = false )
{
if( fname ) {
int i = 0;
int j = 0;
FILE *fp = NULL;
fp = fopen( fname, "w" );
if ( fp == NULL ) {
fprintf( stderr, "\nCould not open file %s for writing.\n", fname );
exit( 0 );
}
fprintf( fp, "%d\n", n );
for ( i = 0; i < n; ++i) {
for ( j = 0; j <= i; ++j ) {
fprintf( fp, "%lf ", A[j*n+i] );
}
if ( !is_triangular ) {
for ( ; j < n; ++j ) {
fprintf( fp, "%lf ", A[i*n+j] );
}
} else {
for ( ; j < n; ++j ) {
fprintf( fp, "%lf ", 0.0 );
}
}
fprintf( fp, "\n" );
}
if ( is_triangular ) {
fprintf( fp, "\n" );
for ( i = 0; i < n; ++i ) {
for ( j = 0; j < i; ++j ) {
fprintf( fp, "%lf ", 0.0 );
}
for ( ; j < n; ++j ) {
fprintf( fp, "%lf ", A[i*n+j] );
}
fprintf( fp, "\n" );
}
}
fclose( fp );
}
}

View File

@@ -0,0 +1,415 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks. Cholesky sample</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,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
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks.<br>Cholesky sample</h1>
</div>
<p>
This directory contains an example of several versions of Cholesky Factorization algorithm.
<br>
<br><b>dpotrf</b>: An implementation that calls the Intel&reg; Math Kernel Library (Intel&reg; MKL) dpotrf function to directly perform the factorization. This can be a serial implementation or threaded implementation depending on the version of the Intel MKL library that is linked against.
<br>
<br><b>crout</b>: A serial implementation that uses the Crout-Cholesky algorithm for factorization. The same approach is parallelized for the other Intel&reg; Threading Building Blocks (Intel&reg; TBB) based approaches below.
<br>
<br><b>depend</b>: A parallel version of Crout-Cholesky factorization that uses an Intel TBB flow graph. This version uses a dependence graph made solely of continue_node objects. This an inspector-executor approach, where a loop nest that is similar to the serial implementation is used to create an unrolled version of the computation. Where the Intel MKL calls would have been made in the original serial implementation of Crout-Cholesky, instead nodes are created and these nodes are linked by edges to the other nodes that they are dependent upon. The resulting graph is relatively large, with a node for each instance of each Intel MKL call. For example, there are many nodes that call dtrsm; one for each invocation of dtrsm in the serial implementation. The is very little overhead in message management for this version and so it is often the highest performing.
<br>
<br><b>join</b>: A parallel version of Crout-Cholesky factorization that uses an Intel TBB flow graph. This version uses a data flow approach. This is a small, compact graph that passes tiles along its edges. There is one node per type of Intel MKL call, plus join_nodes that combine the inputs required for each call. So for example, there is only a single node that applies all calls to dtrsm. This node is invoked when the tiles that hold the inputs and outputs for an invocation are matched together in the tag-matching join_node that precedes it. The tag represents the iteration values of the i, j, k loops in the serial implementation at that invocation of the call. There is some overhead in message matching and forwarding, so it may not perform as well as the dependence graph implementation.
<br>
<br>This sample code requires a recent Intel TBB library (one that supports the flow graph). And also the Intel MKL library.
</p>
<div class="changes">
<div class="h3-alike">System Requirements</div>
<input type="checkbox">
<div class="show-hide">
<p>
For the most up to date system requirements, see the <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a>
</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Files</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="cholesky.cpp">cholesky.cpp</a>
<dd>Source code for example.
<dt><a href="init.cpp">init.cpp</a>
<dd>Source code for example.
<dt><a href="Makefile">Makefile</a>
<dd>Makefile for building the example.
</dl>
</div>
</div>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="msvs/">msvs</a>
<dd>Contains Microsoft* Visual Studio* workspace for building and running the example (Windows* systems only).
<dt><a href="xcode/">xcode</a>
<dd>Contains Xcode* IDE workspace for building and running the example (macOS* systems only).
</dl>
<p>For information about the minimum supported version of IDE, see <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a></p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Build instructions</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<p>General build directions can be found <a href="../../index.html">here</a>.</p>
<p>Also, you need to source Intel MKL environment variables.</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Usage</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><tt>cholesky [<i>size=value</i>] [<i>blocksize=value</i>] [<i>num_trials=value</i>] [<i>output_prefix=value</i>] [<i>algorithm=value</i>] [<i>num_tbb_threads=value</i>] [<i>input_file=value</i>] [<i>-x</i>] [<i>-h</i>] [<i>size</i> [<i>blocksize</i> [<i>num_trials</i> [<i>output_prefix</i> [<i>algorithm</i> [<i>num_tbb_threads</i>]]]]]]</tt>
<dd>where:
<br><tt><i>size</i></tt> - the row/column size of NxN matrix (size &lt;= 46000)
<br><tt><i>blocksize</i></tt> - the block size; size must be a multiple of the blocksize
<br><tt><i>num_trials</i></tt> - the number of times to run each algorithm
<br><tt><i>output_prefix</i></tt> - if provided the prefix will be prepended to output files:
<i>output_prefix_posdef.txt</i> and
<i>output_prefix_X.txt</i>; where <i>X</i> is the algorithm used
<br>if <tt><i>output_prefix</i></tt> is not provided, no output will be written
<br><tt><i>algorithm</i></tt> - name of the used algorithm - can be dpotrf, crout, depend or join
<br><tt><i>num_tbb_threads</i></tt> - number of started TBB threads
<br><tt><i>input_file</i></tt> - if provided it will be read to get the input matrix
<br><tt><i>-x</i></tt> - skips all validation
<br><tt><i>-h</i></tt> - show this message
</dl>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a>
<hr>
<div class="changes">
<div class="h3-alike">Legal Information</div>
<input type="checkbox">
<div class="show-hide">
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,318 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
A1F593A60B8F042A00073279 /* Cholesky.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1F593A50B8F042A00073279 /* Cholesky.cpp */; };
A1F593A60B8F053A00073279 /* init.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1F593A50B8F053A00073279 /* init.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
C3C58951218B5ACC00DAC94C /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.intel.compilers.icc.latest;
fileType = sourcecode.cpp;
isEditable = 1;
outputFiles = (
);
script = "# Type a script or drag a script file from your workspace to insert its path.\n";
};
/* End PBXBuildRule section */
/* Begin PBXCopyFilesBuildPhase section */
8DD76F690486A84900D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 12;
dstPath = "";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
8DD76F6C0486A84900D96B5E /* Cholesky */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Cholesky; sourceTree = BUILT_PRODUCTS_DIR; };
A1F593A50B8F042A00073279 /* Cholesky.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Cholesky.cpp; path = ../Cholesky.cpp; sourceTree = SOURCE_ROOT; };
A1F593A50B8F053A00073279 /* init.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = init.cpp; path = ../init.cpp; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8DD76F660486A84900D96B5E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
08FB7794FE84155DC02AAC07 /* Cholesky */ = {
isa = PBXGroup;
children = (
08FB7795FE84155DC02AAC07 /* Source */,
1AB674ADFE9D54B511CA2CBB /* Products */,
);
name = Cholesky;
sourceTree = "<group>";
};
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
A1F593A50B8F042A00073279 /* Cholesky.cpp */,
A1F593A50B8F053A00073279 /* init.cpp */,
);
name = Source;
sourceTree = "<group>";
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8DD76F6C0486A84900D96B5E /* Cholesky */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8DD76F620486A84900D96B5E /* Cholesky */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "Cholesky" */;
buildPhases = (
8DD76F640486A84900D96B5E /* Sources */,
8DD76F660486A84900D96B5E /* Frameworks */,
8DD76F690486A84900D96B5E /* CopyFiles */,
);
buildRules = (
C3C58951218B5ACC00DAC94C /* PBXBuildRule */,
);
dependencies = (
);
name = Cholesky;
productInstallPath = "$(HOME)/bin";
productName = Cholesky;
productReference = 8DD76F6C0486A84900D96B5E /* Cholesky */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1000;
};
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "cholesky" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,
);
mainGroup = 08FB7794FE84155DC02AAC07 /* Cholesky */;
projectDirPath = "";
projectRoot = "";
targets = (
8DD76F620486A84900D96B5E /* Cholesky */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
8DD76F640486A84900D96B5E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A1F593A60B8F042A00073279 /* Cholesky.cpp in Sources */,
A1F593A60B8F053A00073279 /* init.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
A1F593C60B8F0E6E00073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = Cholesky;
ZERO_LINK = NO;
};
name = Debug64;
};
A1F593C70B8F0E6E00073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = Cholesky;
ZERO_LINK = NO;
};
name = Release64;
};
A1F593C80B8F0E6E00073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
/opt/intel/tbb/include,
/opt/intel/mkl/include,
);
ICC_CXX_LANG_DIALECT = "c++11";
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib $(MKLROOT)/lib /opt/intel/mkl/lib";
LIBRARY_SEARCH_PATHS = (
/opt/intel/tbb/lib,
/opt/intel/mkl/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
ONLY_ACTIVE_ARCH = YES;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-m64",
);
OTHER_LDFLAGS = (
"-m64",
"-ltbb_debug",
"-lmkl_intel_lp64",
"-lmkl_sequential",
"-lmkl_core",
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Debug64;
};
A1F593C90B8F0E6E00073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
/opt/intel/tbb/include,
/opt/intel/mkl/include,
);
ICC_CXX_LANG_DIALECT = "c++11";
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib $(MKLROOT)/lib /opt/intel/mkl/lib";
LIBRARY_SEARCH_PATHS = (
/opt/intel/tbb/lib,
/opt/intel/mkl/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-m64",
);
OTHER_LDFLAGS = (
"-m64",
"-ltbb",
"-lmkl_intel_lp64",
"-lmkl_sequential",
"-lmkl_core",
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Release64;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "Cholesky" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F593C60B8F0E6E00073279 /* Debug64 */,
A1F593C70B8F0E6E00073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "cholesky" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F593C80B8F0E6E00073279 /* Debug64 */,
A1F593C90B8F0E6E00073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8DD76F620486A84900D96B5E"
BuildableName = "Cholesky"
BlueprintName = "Cholesky"
ReferencedContainer = "container:cholesky.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug64"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8DD76F620486A84900D96B5E"
BuildableName = "Cholesky"
BlueprintName = "Cholesky"
ReferencedContainer = "container:cholesky.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Release64"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8DD76F620486A84900D96B5E"
BuildableName = "Cholesky"
BlueprintName = "Cholesky"
ReferencedContainer = "container:cholesky.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<CommandLineArguments>
<CommandLineArgument
argument = "4"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "2"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release64"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8DD76F620486A84900D96B5E"
BuildableName = "Cholesky"
BlueprintName = "Cholesky"
ReferencedContainer = "container:cholesky.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug64">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release64"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -0,0 +1,44 @@
# Copyright (c) 2005-2020 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.
# Common Makefile that builds and runs example.
# Just specify your program basename
PROG=dining_philosophers
ARGS= auto 5
LIGHT_ARGS= auto 3
# Trying to find if icl.exe is set
CXX1 = $(TBB_CXX)-
CXX2 = $(CXX1:icl.exe-=icl.exe)
CXX = $(CXX2:-=cl.exe)
# The C++ compiler options
MYCXXFLAGS = /TP /EHsc /W3 /nologo /D _CONSOLE /D _MBCS /D WIN32 /D _CRT_SECURE_NO_DEPRECATE $(CXXFLAGS)
MYLDFLAGS =/INCREMENTAL:NO /NOLOGO /DEBUG /FIXED:NO $(LDFLAGS)
all: release test
release:
$(CXX) ./dining_philosophers.cpp /MD /O2 /D NDEBUG $(MYCXXFLAGS) /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
debug:
$(CXX) ./dining_philosophers.cpp /MDd /Od /Zi /D _DEBUG $(MYCXXFLAGS) /link tbb_debug.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
profile:
$(CXX) ./dining_philosophers.cpp /MD /O2 /Zi /D NDEBUG $(MYCXXFLAGS) /D TBB_USE_THREADING_TOOLS /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
clean:
@cmd.exe /C del $(PROG).exe *.obj *.?db *.manifest
test:
$(PROG) $(ARGS)
light_test:
$(PROG) $(LIGHT_ARGS)

View File

@@ -0,0 +1,303 @@
/*
Copyright (c) 2005-2020 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.
*/
#if _MSC_VER
// Suppress "decorated name length exceeded, name was truncated" warning
#pragma warning (disable: 4503)
#endif
#include "tbb/flow_graph.h"
#include "tbb/tick_count.h"
#include "tbb/spin_mutex.h"
#include "tbb/global_control.h"
#include <iostream>
#include <thread>
#include <chrono>
#include "../../common/utility/utility.h"
#include "../../common/utility/get_default_num_threads.h"
#include <cstdlib>
#include <cstdio>
// Each philosopher is an object, and is invoked in the think() function_node, the
// eat() function_node and forward() multifunction_node.
//
// The graph is constructed, and each think() function_node is started with a continue_msg.
//
// The philosopher will think, then gather two chopsticks, eat, place the chopsticks back,
// and if they have not completed the required number of cycles, will start to think() again
// by sending a continue_msg to their corresponding think() function_node.
//
// The reserving join has as its inputs the left and right chopstick queues an a queue
// that stores the continue_msg emitted by the function_node after think()ing is done.
// When all three inputs are available, a tuple of the inputs will be forwarded to the
// eat() function_node. The output of the eat() function_node is sent to the forward()
// multifunction_node.
const std::chrono::seconds think_time (1);
const std::chrono::seconds eat_time (1);
const int num_times = 10;
tbb::tick_count t0;
bool verbose = false;
const char *names[] = { "Archimedes", "Bakunin", "Confucius", "Democritus", "Euclid"
, "Favorinus", "Geminus", "Heraclitus", "Ichthyas", "Jason of Nysa",
"Kant", "Lavrov", "Metrocles", "Nausiphanes", "Onatas", "Phaedrus",
"Quillot", "Russell", "Socrates", "Thales", "Udayana",
"Vernadsky", "Wittgenstein", "Xenophilus", "Yen Yuan", "Zenodotus"
};
const int NumPhilosophers = sizeof(names) / sizeof(char*);
struct RunOptions {
utility::thread_number_range threads;
int number_of_philosophers;
bool silent;
RunOptions(utility::thread_number_range threads_, int number_of_philosophers_, bool silent_) :
threads(threads_), number_of_philosophers(number_of_philosophers_), silent(silent_) { }
};
RunOptions ParseCommandLine(int argc, char *argv[]) {
int auto_threads = utility::get_default_num_threads();
utility::thread_number_range threads(utility::get_default_num_threads, auto_threads, auto_threads);
int nPhilosophers = 5;
bool verbose = false;
char charbuf[100];
std::sprintf(charbuf, "%d", NumPhilosophers);
std::string pCount = "how many philosophers, from 2-";
pCount += charbuf;
utility::cli_argument_pack cli_pack;
cli_pack.positional_arg(threads, "n-of_threads", utility::thread_number_range_desc)
.positional_arg(nPhilosophers, "n-of-philosophers", pCount)
.arg(verbose,"verbose","verbose output");
utility::parse_cli_arguments(argc, argv, cli_pack);
if(nPhilosophers < 2 || nPhilosophers > NumPhilosophers) {
std::cout << "Number of philosophers (" << nPhilosophers << ") out of range [2:" << NumPhilosophers << "]\n";
std::cout << cli_pack.usage_string(argv[0]) << std::flush;
std::exit(1);
}
return RunOptions(threads, nPhilosophers,!verbose);
}
tbb::spin_mutex my_mutex;
class chopstick {};
using namespace tbb::flow;
typedef tbb::flow::tuple<continue_msg, chopstick, chopstick> join_output;
typedef join_node< join_output, reserving > join_node_type;
typedef function_node<continue_msg, continue_msg> think_node_type;
typedef function_node<join_output, continue_msg> eat_node_type;
typedef multifunction_node<continue_msg, join_output> forward_node_type;
class philosopher {
public:
philosopher( const char *name ) :
my_name(name), my_count(num_times) { }
~philosopher() {
}
void check();
const char *name() const { return my_name; }
private:
friend std::ostream& operator<<(std::ostream& o, philosopher const &p);
const char *my_name;
int my_count;
friend class think_node_body;
friend class eat_node_body;
friend class forward_node_body;
void think( );
void eat();
void forward( const continue_msg &in, forward_node_type::output_ports_type &out_ports );
};
std::ostream& operator<<(std::ostream& o, philosopher const &p) {
o << "< philosopher[" << reinterpret_cast<uintptr_t>(const_cast<philosopher *>(&p)) << "] " << p.name()
<< ", my_count=" << p.my_count;
return o;
}
class think_node_body {
philosopher& my_philosopher;
public:
think_node_body( philosopher &p ) : my_philosopher(p) { }
think_node_body( const think_node_body &other ) : my_philosopher(other.my_philosopher) { }
continue_msg operator()( continue_msg /*m*/) {
my_philosopher.think();
return continue_msg();
}
};
class eat_node_body {
philosopher &my_philosopher;
public:
eat_node_body( philosopher &p) : my_philosopher(p) {}
eat_node_body( const eat_node_body &other ) : my_philosopher(other.my_philosopher) { }
continue_msg operator()(const join_output &in) {
my_philosopher.eat();
return continue_msg();
}
};
class forward_node_body {
philosopher &my_philosopher;
public:
forward_node_body( philosopher &p) : my_philosopher(p) {}
forward_node_body( const forward_node_body &other ) : my_philosopher(other.my_philosopher) { }
void operator()( const continue_msg &in, forward_node_type::output_ports_type &out) {
my_philosopher.forward( in, out);
}
};
void philosopher::check() {
if ( my_count != 0 ) {
std::printf("ERROR: philosopher %s still had to run %d more times\n", name(), my_count);
std::exit(1);
}
}
void philosopher::forward( const continue_msg &/*in*/, forward_node_type::output_ports_type &out_ports ) {
if(my_count < 0) abort();
--my_count;
(void)tbb::flow::get<1>(out_ports).try_put(chopstick());
(void)tbb::flow::get<2>(out_ports).try_put(chopstick());
if (my_count > 0) {
(void)tbb::flow::get<0>(out_ports).try_put(continue_msg()); //start thinking again
} else {
if(verbose) {
tbb::spin_mutex::scoped_lock lock(my_mutex);
std::printf("%s has left the building\n", name());
}
}
}
void philosopher::eat() {
if(verbose) {
tbb::spin_mutex::scoped_lock lock(my_mutex);
std::printf("%s eating\n", name());
}
std::this_thread::sleep_for(eat_time);
if(verbose) {
tbb::spin_mutex::scoped_lock lock(my_mutex);
std::printf("%s done eating\n", name());
}
}
void philosopher::think() {
if(verbose) {
tbb::spin_mutex::scoped_lock lock(my_mutex);
std::printf("%s thinking\n", name());
}
std::this_thread::sleep_for(think_time);
if(verbose) {
tbb::spin_mutex::scoped_lock lock(my_mutex);
std::printf("%s done thinking\n", name());
}
}
typedef queue_node<continue_msg> thinking_done_type;
int main(int argc, char *argv[]) {
try {
tbb::tick_count main_time = tbb::tick_count::now();
int num_threads;
int num_philosophers;
RunOptions options = ParseCommandLine(argc, argv);
num_philosophers = options.number_of_philosophers;
verbose = !options.silent;
for(num_threads = options.threads.first; num_threads <= options.threads.last; num_threads = options.threads.step(num_threads)) {
tbb::global_control c(tbb::global_control::max_allowed_parallelism, num_threads);
graph g;
if(verbose) std::cout << std::endl << num_philosophers << " philosophers with "
<< num_threads << " threads" << std::endl << std::endl;
t0 = tbb::tick_count::now();
std::vector<queue_node<chopstick> > places(num_philosophers, queue_node<chopstick>(g));
std::vector<philosopher> philosophers;
philosophers.reserve(num_philosophers);
std::vector<think_node_type *> think_nodes;
think_nodes.reserve(num_philosophers);
std::vector<thinking_done_type> done_vector(num_philosophers, thinking_done_type(g));
std::vector<join_node_type> join_vector(num_philosophers,join_node_type(g));
std::vector<eat_node_type *> eat_nodes;
eat_nodes.reserve(num_philosophers);
std::vector<forward_node_type *> forward_nodes;
forward_nodes.reserve(num_philosophers);
for ( int i = 0; i < num_philosophers; ++i ) {
places[i].try_put(chopstick());
philosophers.push_back( philosopher( names[i] ) ); // allowed because of default generated assignment
if(verbose) {
tbb::spin_mutex::scoped_lock lock(my_mutex);
std::cout << "Built philosopher " << philosophers[i] << std::endl;
}
think_nodes.push_back(new think_node_type(g, unlimited, think_node_body(philosophers[i])));
eat_nodes.push_back( new eat_node_type(g, unlimited, eat_node_body(philosophers[i])));
forward_nodes.push_back( new forward_node_type(g, unlimited, forward_node_body(philosophers[i])));
}
// attach chopstick buffers and think function_nodes to joins
for(int i = 0; i < num_philosophers; ++i) {
make_edge( *think_nodes[i], done_vector[i] );
make_edge( done_vector[i], input_port<0>(join_vector[i]) );
make_edge( places[i], input_port<1>(join_vector[i]) ); // left chopstick
make_edge( places[(i+1) % num_philosophers], input_port<2>(join_vector[i]) ); // right chopstick
make_edge( join_vector[i], *eat_nodes[i] );
make_edge( *eat_nodes[i], *forward_nodes[i] );
make_edge( output_port<0>(*forward_nodes[i]), *think_nodes[i] );
make_edge( output_port<1>(*forward_nodes[i]), places[i] );
make_edge( output_port<2>(*forward_nodes[i]), places[(i+1) % num_philosophers] );
}
// start all the philosophers thinking
for(int i = 0; i < num_philosophers; ++i) think_nodes[i]->try_put(continue_msg());
g.wait_for_all();
tbb::tick_count t1 = tbb::tick_count::now();
if(verbose) std::cout << std::endl << num_philosophers << " philosophers with "
<< num_threads << " threads have taken " << (t1-t0).seconds() << "seconds" << std::endl;
for ( int i = 0; i < num_philosophers; ++i ) philosophers[i].check();
for(int i = 0; i < num_philosophers; ++i) {
delete think_nodes[i];
delete eat_nodes[i];
delete forward_nodes[i];
}
}
utility::report_elapsed_time((tbb::tick_count::now() - main_time).seconds());
return 0;
} catch(std::exception& e) {
std::cerr<<"error occurred. error text is :\"" <<e.what()<<"\"\n";
return 1;
}
}

View File

@@ -0,0 +1,383 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks. Dining_philosophers sample</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,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
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks.<br>Dining_philosophers sample</h1>
</div>
<p>
The Dining Philosophers problem demonstrates tbb::flow and the use of the reserving join node to
solve the potential deadlock.
<br><br>
This program runs some number of philosophers in parallel, each thinking and then waiting for chopsticks
to be available before eating. Eating and thinking are implemented with sleep(). The chopstick positions are represented by a queue_node with one item.
</p>
<div class="changes">
<div class="h3-alike">System Requirements</div>
<input type="checkbox">
<div class="show-hide">
<p>
For the most up to date system requirements, see the <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a>
</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Files</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="dining_philosophers.cpp">dining_philosophers.cpp</a>
<dd>Source code for the example.
<dt><a href="Makefile">Makefile</a>
<dd>Makefile for building the example.
</dl>
</div>
</div>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="msvs/">msvs</a>
<dd>Contains Microsoft* Visual Studio* workspace for building and running the example (Windows* systems only).
<dt><a href="xcode/">xcode</a>
<dd>Contains Xcode* IDE workspace for building and running the example (macOS* systems only).
</dl>
<p>For information about the minimum supported version of IDE, see <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a></p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Build instructions</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<p>General build directions can be found <a href="../../index.html">here</a>.</p>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a>
<hr>
<div class="changes">
<div class="h3-alike">Legal Information</div>
<input type="checkbox">
<div class="show-hide">
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,316 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
A1F593A60B8F042A00073279 /* dining_philosophers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1F593A50B8F042A00073279 /* dining_philosophers.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
C3C58955218B5FE200DAC94C /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.intel.compilers.icc.latest;
fileType = sourcecode.cpp;
isEditable = 1;
outputFiles = (
);
script = "# Type a script or drag a script file from your workspace to insert its path.\n";
};
/* End PBXBuildRule section */
/* Begin PBXCopyFilesBuildPhase section */
8DD76F690486A84900D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 12;
dstPath = "";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
8DD76F6C0486A84900D96B5E /* dining_philosophers */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dining_philosophers; sourceTree = BUILT_PRODUCTS_DIR; };
A1F593A50B8F042A00073279 /* dining_philosophers.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = dining_philosophers.cpp; path = ../dining_philosophers.cpp; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8DD76F660486A84900D96B5E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
08FB7794FE84155DC02AAC07 /* dining_philosophers */ = {
isa = PBXGroup;
children = (
08FB7795FE84155DC02AAC07 /* Source */,
1AB674ADFE9D54B511CA2CBB /* Products */,
);
name = dining_philosophers;
sourceTree = "<group>";
};
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
A1F593A50B8F042A00073279 /* dining_philosophers.cpp */,
);
name = Source;
sourceTree = "<group>";
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8DD76F6C0486A84900D96B5E /* dining_philosophers */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8DD76F620486A84900D96B5E /* dining_philosophers */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "dining_philosophers" */;
buildPhases = (
8DD76F640486A84900D96B5E /* Sources */,
8DD76F660486A84900D96B5E /* Frameworks */,
8DD76F690486A84900D96B5E /* CopyFiles */,
);
buildRules = (
C3C58955218B5FE200DAC94C /* PBXBuildRule */,
);
dependencies = (
);
name = dining_philosophers;
productInstallPath = "$(HOME)/bin";
productName = dining_philosophers;
productReference = 8DD76F6C0486A84900D96B5E /* dining_philosophers */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1000;
};
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "dining_philosophers" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,
);
mainGroup = 08FB7794FE84155DC02AAC07 /* dining_philosophers */;
projectDirPath = "";
projectRoot = "";
targets = (
8DD76F620486A84900D96B5E /* dining_philosophers */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
8DD76F640486A84900D96B5E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A1F593A60B8F042A00073279 /* dining_philosophers.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
A1F593C60B8F0E6E00073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = (
"-m64",
"-ltbb_debug",
);
PRODUCT_NAME = dining_philosophers;
ZERO_LINK = NO;
};
name = Debug64;
};
A1F593C70B8F0E6E00073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = (
"-m64",
"-ltbb",
);
PRODUCT_NAME = dining_philosophers;
ZERO_LINK = NO;
};
name = Release64;
};
A1F593C80B8F0E6E00073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(TBBROOT)/include",
/opt/intel/tbb/include,
);
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
LIBRARY_SEARCH_PATHS = (
"$(TBBROOT)/lib",
/opt/intel/tbb/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
ONLY_ACTIVE_ARCH = YES;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-m64",
);
OTHER_LDFLAGS = (
"-m64",
"-ltbb_debug",
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Debug64;
};
A1F593C90B8F0E6E00073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(TBBROOT)/include",
/opt/intel/tbb/include,
);
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
LIBRARY_SEARCH_PATHS = (
"$(TBBROOT)/lib",
/opt/intel/tbb/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-m64",
);
OTHER_LDFLAGS = (
"-m64",
"-ltbb",
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Release64;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "dining_philosophers" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F593C60B8F0E6E00073279 /* Debug64 */,
A1F593C70B8F0E6E00073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "dining_philosophers" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F593C80B8F0E6E00073279 /* Debug64 */,
A1F593C90B8F0E6E00073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View File

@@ -0,0 +1,53 @@
# Copyright (c) 2005-2020 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.
# Common Makefile that builds and runs example.
# Just specify your program basename
run_cmd=
PROG=fgbzip2
ARGS=-b=9 -a=async_node $(PROG).exe
PERF_RUN_ARGS=-b=9 -a=async_node $(PROG).exe
# Trying to find if icl.exe is set
CXX1 = $(TBB_CXX)-
CXX2 = $(CXX1:icl.exe-=icl.exe)
CXX = $(CXX2:-=cl.exe)
# The C++ compiler options
MYCXXFLAGS = /EHsc /W3 /nologo /D _CONSOLE /D _MBCS /D WIN32 /D _CRT_SECURE_NO_WARNINGS /D _CRT_NONSTDC_NO_DEPRECATE /wd4267 /wd4244
MYLDFLAGS =/INCREMENTAL:NO /NOLOGO /DEBUG /FIXED:NO $(LDFLAGS)
all: release test
release:
$(CXX) *.cpp /MD /O2 /Zi /D NDEBUG $(MYCXXFLAGS) /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
debug:
$(CXX) *.cpp /MDd /Od /Zi /D TBB_USE_DEBUG /D _DEBUG $(MYCXXFLAGS) /link tbb_debug.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
profile:
$(CXX) *.cpp /MD /O2 /Zi /D NDEBUG $(MYCXXFLAGS) /D TBB_USE_THREADING_TOOLS /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
clean:
@cmd.exe /C del $(PROG).exe *.obj *.?db *.manifest *.bz2
test:
$(PROG) $(ARGS)
perf_build: release
perf_run:
$(PROG) $(PERF_RUN_ARGS)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,330 @@
/*
Copyright (c) 2005-2020 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.
*/
/*-------------------------------------------------------------*/
/*--- Public header file for the library. ---*/
/*--- bzlib.h ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
The original source for this example:
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
This program, "bzip2", the associated library "libbzip2", and all
documentation, are copyright (C) 1996-2010 Julian R Seward. All
rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
3. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
4. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Julian Seward, jseward@bzip.org
bzip2/libbzip2 version 1.0.6 of 6 September 2010
------------------------------------------------------------------ */
#ifndef _BZLIB_H
#define _BZLIB_H
#ifdef __cplusplus
extern "C" {
#endif
#define BZ_RUN 0
#define BZ_FLUSH 1
#define BZ_FINISH 2
#define BZ_OK 0
#define BZ_RUN_OK 1
#define BZ_FLUSH_OK 2
#define BZ_FINISH_OK 3
#define BZ_STREAM_END 4
#define BZ_SEQUENCE_ERROR (-1)
#define BZ_PARAM_ERROR (-2)
#define BZ_MEM_ERROR (-3)
#define BZ_DATA_ERROR (-4)
#define BZ_DATA_ERROR_MAGIC (-5)
#define BZ_IO_ERROR (-6)
#define BZ_UNEXPECTED_EOF (-7)
#define BZ_OUTBUFF_FULL (-8)
#define BZ_CONFIG_ERROR (-9)
typedef
struct {
char *next_in;
unsigned int avail_in;
unsigned int total_in_lo32;
unsigned int total_in_hi32;
char *next_out;
unsigned int avail_out;
unsigned int total_out_lo32;
unsigned int total_out_hi32;
void *state;
void *(*bzalloc)(void *,int,int);
void (*bzfree)(void *,void *);
void *opaque;
}
bz_stream;
#ifndef BZ_IMPORT
#define BZ_EXPORT
#endif
#ifndef BZ_NO_STDIO
/* Need a definitition for FILE */
#include <stdio.h>
#endif
#ifdef _WIN32
# include <windows.h>
# ifdef small
/* windows.h define small to char */
# undef small
# endif
# ifdef BZ_EXPORT
# define BZ_API(func) WINAPI func
# define BZ_EXTERN extern
# else
/* import windows dll dynamically */
# define BZ_API(func) (WINAPI * func)
# define BZ_EXTERN
# endif
#else
# define BZ_API(func) func
# define BZ_EXTERN extern
#endif
/*-- Core (low-level) library functions --*/
BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
bz_stream* strm,
int blockSize100k,
int verbosity,
int workFactor
);
BZ_EXTERN int BZ_API(BZ2_bzCompress) (
bz_stream* strm,
int action
);
BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
bz_stream* strm
);
BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
bz_stream *strm,
int verbosity,
int small
);
BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
bz_stream* strm
);
BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
bz_stream *strm
);
/*-- High(er) level library functions --*/
#ifndef BZ_NO_STDIO
#define BZ_MAX_UNUSED 5000
typedef void BZFILE;
BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
int* bzerror,
FILE* f,
int verbosity,
int small,
void* unused,
int nUnused
);
BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
int* bzerror,
BZFILE* b
);
BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
int* bzerror,
BZFILE* b,
void** unused,
int* nUnused
);
BZ_EXTERN int BZ_API(BZ2_bzRead) (
int* bzerror,
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
int* bzerror,
FILE* f,
int blockSize100k,
int verbosity,
int workFactor
);
BZ_EXTERN void BZ_API(BZ2_bzWrite) (
int* bzerror,
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
int* bzerror,
BZFILE* b,
int abandon,
unsigned int* nbytes_in,
unsigned int* nbytes_out
);
BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
int* bzerror,
BZFILE* b,
int abandon,
unsigned int* nbytes_in_lo32,
unsigned int* nbytes_in_hi32,
unsigned int* nbytes_out_lo32,
unsigned int* nbytes_out_hi32
);
#endif
/*-- Utility functions --*/
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
char* dest,
unsigned int* destLen,
char* source,
unsigned int sourceLen,
int blockSize100k,
int verbosity,
int workFactor
);
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
char* dest,
unsigned int* destLen,
char* source,
unsigned int sourceLen,
int small,
int verbosity
);
/*--
Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
to support better zlib compatibility.
This code is not _officially_ part of libbzip2 (yet);
I haven't tested it, documented it, or considered the
threading-safeness of it.
If this code breaks, please contact both Yoshioka and me.
--*/
BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
void
);
#ifndef BZ_NO_STDIO
BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
const char *path,
const char *mode
);
BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
int fd,
const char *mode
);
BZ_EXTERN int BZ_API(BZ2_bzread) (
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN int BZ_API(BZ2_bzwrite) (
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN int BZ_API(BZ2_bzflush) (
BZFILE* b
);
BZ_EXTERN void BZ_API(BZ2_bzclose) (
BZFILE* b
);
BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
BZFILE *b,
int *errnum
);
#endif
#ifdef __cplusplus
}
#endif
#endif
/*-------------------------------------------------------------*/
/*--- end bzlib.h ---*/
/*-------------------------------------------------------------*/

View File

@@ -0,0 +1,557 @@
/*
Copyright (c) 2005-2020 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.
*/
/*-------------------------------------------------------------*/
/*--- Private header file for the library. ---*/
/*--- bzlib_private.h ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
The original source for this example:
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
This program, "bzip2", the associated library "libbzip2", and all
documentation, are copyright (C) 1996-2010 Julian R Seward. All
rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
3. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
4. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Julian Seward, jseward@bzip.org
bzip2/libbzip2 version 1.0.6 of 6 September 2010
------------------------------------------------------------------ */
#ifndef _BZLIB_PRIVATE_H
#define _BZLIB_PRIVATE_H
#include <stdlib.h>
#ifndef BZ_NO_STDIO
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#endif
#include "bzlib.h"
/*-- General stuff. --*/
#define BZ_VERSION "1.0.6, 6-Sept-2010"
typedef char Char;
typedef unsigned char Bool;
typedef unsigned char UChar;
typedef int Int32;
typedef unsigned int UInt32;
typedef short Int16;
typedef unsigned short UInt16;
#define True ((Bool)1)
#define False ((Bool)0)
#ifndef __GNUC__
#define __inline__ /* */
#endif
#ifndef BZ_NO_STDIO
extern void BZ2_bz__AssertH__fail ( int errcode );
#define AssertH(cond,errcode) \
{ if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
#if BZ_DEBUG
#define AssertD(cond,msg) \
{ if (!(cond)) { \
fprintf ( stderr, \
"\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
exit(1); \
}}
#else
#define AssertD(cond,msg) /* */
#endif
#define VPrintf0(zf) \
fprintf(stderr,zf)
#define VPrintf1(zf,za1) \
fprintf(stderr,zf,za1)
#define VPrintf2(zf,za1,za2) \
fprintf(stderr,zf,za1,za2)
#define VPrintf3(zf,za1,za2,za3) \
fprintf(stderr,zf,za1,za2,za3)
#define VPrintf4(zf,za1,za2,za3,za4) \
fprintf(stderr,zf,za1,za2,za3,za4)
#define VPrintf5(zf,za1,za2,za3,za4,za5) \
fprintf(stderr,zf,za1,za2,za3,za4,za5)
#else
extern void bz_internal_error ( int errcode );
#define AssertH(cond,errcode) \
{ if (!(cond)) bz_internal_error ( errcode ); }
#define AssertD(cond,msg) do { } while (0)
#define VPrintf0(zf) do { } while (0)
#define VPrintf1(zf,za1) do { } while (0)
#define VPrintf2(zf,za1,za2) do { } while (0)
#define VPrintf3(zf,za1,za2,za3) do { } while (0)
#define VPrintf4(zf,za1,za2,za3,za4) do { } while (0)
#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
#endif
#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp))
/*-- Header bytes. --*/
#define BZ_HDR_B 0x42 /* 'B' */
#define BZ_HDR_Z 0x5a /* 'Z' */
#define BZ_HDR_h 0x68 /* 'h' */
#define BZ_HDR_0 0x30 /* '0' */
/*-- Constants for the back end. --*/
#define BZ_MAX_ALPHA_SIZE 258
#define BZ_MAX_CODE_LEN 23
#define BZ_RUNA 0
#define BZ_RUNB 1
#define BZ_N_GROUPS 6
#define BZ_G_SIZE 50
#define BZ_N_ITERS 4
#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
/*-- Stuff for randomising repetitive blocks. --*/
extern Int32 BZ2_rNums[512];
#define BZ_RAND_DECLS \
Int32 rNToGo; \
Int32 rTPos \
#define BZ_RAND_INIT_MASK \
s->rNToGo = 0; \
s->rTPos = 0 \
#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
#define BZ_RAND_UPD_MASK \
if (s->rNToGo == 0) { \
s->rNToGo = BZ2_rNums[s->rTPos]; \
s->rTPos++; \
if (s->rTPos == 512) s->rTPos = 0; \
} \
s->rNToGo--;
/*-- Stuff for doing CRCs. --*/
extern UInt32 BZ2_crc32Table[256];
#define BZ_INITIALISE_CRC(crcVar) \
{ \
crcVar = 0xffffffffL; \
}
#define BZ_FINALISE_CRC(crcVar) \
{ \
crcVar = ~(crcVar); \
}
#define BZ_UPDATE_CRC(crcVar,cha) \
{ \
crcVar = (crcVar << 8) ^ \
BZ2_crc32Table[(crcVar >> 24) ^ \
((UChar)cha)]; \
}
/*-- States and modes for compression. --*/
#define BZ_M_IDLE 1
#define BZ_M_RUNNING 2
#define BZ_M_FLUSHING 3
#define BZ_M_FINISHING 4
#define BZ_S_OUTPUT 1
#define BZ_S_INPUT 2
#define BZ_N_RADIX 2
#define BZ_N_QSORT 12
#define BZ_N_SHELL 18
#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
/*-- Structure holding all the compression-side stuff. --*/
typedef
struct {
/* pointer back to the struct bz_stream */
bz_stream* strm;
/* mode this stream is in, and whether inputting */
/* or outputting data */
Int32 mode;
Int32 state;
/* remembers avail_in when flush/finish requested */
UInt32 avail_in_expect;
/* for doing the block sorting */
UInt32* arr1;
UInt32* arr2;
UInt32* ftab;
Int32 origPtr;
/* aliases for arr1 and arr2 */
UInt32* ptr;
UChar* block;
UInt16* mtfv;
UChar* zbits;
/* for deciding when to use the fallback sorting algorithm */
Int32 workFactor;
/* run-length-encoding of the input */
UInt32 state_in_ch;
Int32 state_in_len;
BZ_RAND_DECLS;
/* input and output limits and current posns */
Int32 nblock;
Int32 nblockMAX;
Int32 numZ;
Int32 state_out_pos;
/* map of bytes used in block */
Int32 nInUse;
Bool inUse[256];
UChar unseqToSeq[256];
/* the buffer for bit stream creation */
UInt32 bsBuff;
Int32 bsLive;
/* block and combined CRCs */
UInt32 blockCRC;
UInt32 combinedCRC;
/* misc administratium */
Int32 verbosity;
Int32 blockNo;
Int32 blockSize100k;
/* stuff for coding the MTF values */
Int32 nMTF;
Int32 mtfFreq [BZ_MAX_ALPHA_SIZE];
UChar selector [BZ_MAX_SELECTORS];
UChar selectorMtf[BZ_MAX_SELECTORS];
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
/* second dimension: only 3 needed; 4 makes index calculations faster */
UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
}
EState;
/*-- externs for compression. --*/
extern void
BZ2_blockSort ( EState* );
extern void
BZ2_compressBlock ( EState*, Bool );
extern void
BZ2_bsInitWrite ( EState* );
extern void
BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
extern void
BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
/*-- states for decompression. --*/
#define BZ_X_IDLE 1
#define BZ_X_OUTPUT 2
#define BZ_X_MAGIC_1 10
#define BZ_X_MAGIC_2 11
#define BZ_X_MAGIC_3 12
#define BZ_X_MAGIC_4 13
#define BZ_X_BLKHDR_1 14
#define BZ_X_BLKHDR_2 15
#define BZ_X_BLKHDR_3 16
#define BZ_X_BLKHDR_4 17
#define BZ_X_BLKHDR_5 18
#define BZ_X_BLKHDR_6 19
#define BZ_X_BCRC_1 20
#define BZ_X_BCRC_2 21
#define BZ_X_BCRC_3 22
#define BZ_X_BCRC_4 23
#define BZ_X_RANDBIT 24
#define BZ_X_ORIGPTR_1 25
#define BZ_X_ORIGPTR_2 26
#define BZ_X_ORIGPTR_3 27
#define BZ_X_MAPPING_1 28
#define BZ_X_MAPPING_2 29
#define BZ_X_SELECTOR_1 30
#define BZ_X_SELECTOR_2 31
#define BZ_X_SELECTOR_3 32
#define BZ_X_CODING_1 33
#define BZ_X_CODING_2 34
#define BZ_X_CODING_3 35
#define BZ_X_MTF_1 36
#define BZ_X_MTF_2 37
#define BZ_X_MTF_3 38
#define BZ_X_MTF_4 39
#define BZ_X_MTF_5 40
#define BZ_X_MTF_6 41
#define BZ_X_ENDHDR_2 42
#define BZ_X_ENDHDR_3 43
#define BZ_X_ENDHDR_4 44
#define BZ_X_ENDHDR_5 45
#define BZ_X_ENDHDR_6 46
#define BZ_X_CCRC_1 47
#define BZ_X_CCRC_2 48
#define BZ_X_CCRC_3 49
#define BZ_X_CCRC_4 50
/*-- Constants for the fast MTF decoder. --*/
#define MTFA_SIZE 4096
#define MTFL_SIZE 16
/*-- Structure holding all the decompression-side stuff. --*/
typedef
struct {
/* pointer back to the struct bz_stream */
bz_stream* strm;
/* state indicator for this stream */
Int32 state;
/* for doing the final run-length decoding */
UChar state_out_ch;
Int32 state_out_len;
Bool blockRandomised;
BZ_RAND_DECLS;
/* the buffer for bit stream reading */
UInt32 bsBuff;
Int32 bsLive;
/* misc administratium */
Int32 blockSize100k;
Bool smallDecompress;
Int32 currBlockNo;
Int32 verbosity;
/* for undoing the Burrows-Wheeler transform */
Int32 origPtr;
UInt32 tPos;
Int32 k0;
Int32 unzftab[256];
Int32 nblock_used;
Int32 cftab[257];
Int32 cftabCopy[257];
/* for undoing the Burrows-Wheeler transform (FAST) */
UInt32 *tt;
/* for undoing the Burrows-Wheeler transform (SMALL) */
UInt16 *ll16;
UChar *ll4;
/* stored and calculated CRCs */
UInt32 storedBlockCRC;
UInt32 storedCombinedCRC;
UInt32 calculatedBlockCRC;
UInt32 calculatedCombinedCRC;
/* map of bytes used in block */
Int32 nInUse;
Bool inUse[256];
Bool inUse16[16];
UChar seqToUnseq[256];
/* for decoding the MTF values */
UChar mtfa [MTFA_SIZE];
Int32 mtfbase[256 / MTFL_SIZE];
UChar selector [BZ_MAX_SELECTORS];
UChar selectorMtf[BZ_MAX_SELECTORS];
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 minLens[BZ_N_GROUPS];
/* save area for scalars in the main decompress code */
Int32 save_i;
Int32 save_j;
Int32 save_t;
Int32 save_alphaSize;
Int32 save_nGroups;
Int32 save_nSelectors;
Int32 save_EOB;
Int32 save_groupNo;
Int32 save_groupPos;
Int32 save_nextSym;
Int32 save_nblockMAX;
Int32 save_nblock;
Int32 save_es;
Int32 save_N;
Int32 save_curr;
Int32 save_zt;
Int32 save_zn;
Int32 save_zvec;
Int32 save_zj;
Int32 save_gSel;
Int32 save_gMinlen;
Int32* save_gLimit;
Int32* save_gBase;
Int32* save_gPerm;
}
DState;
/*-- Macros for decompression. --*/
#define BZ_GET_FAST(cccc) \
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
s->tPos = s->tt[s->tPos]; \
cccc = (UChar)(s->tPos & 0xff); \
s->tPos >>= 8;
#define BZ_GET_FAST_C(cccc) \
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
c_tPos = c_tt[c_tPos]; \
cccc = (UChar)(c_tPos & 0xff); \
c_tPos >>= 8;
#define SET_LL4(i,n) \
{ if (((i) & 0x1) == 0) \
s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \
s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \
}
#define GET_LL4(i) \
((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
#define SET_LL(i,n) \
{ s->ll16[i] = (UInt16)(n & 0x0000ffff); \
SET_LL4(i, n >> 16); \
}
#define GET_LL(i) \
(((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
#define BZ_GET_SMALL(cccc) \
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
s->tPos = GET_LL(s->tPos);
/*-- externs for decompression. --*/
extern Int32
BZ2_indexIntoF ( Int32, Int32* );
extern Int32
BZ2_decompress ( DState* );
extern void
BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
Int32, Int32, Int32 );
#endif
/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
#ifdef BZ_NO_STDIO
#ifndef NULL
#define NULL 0
#endif
#endif
/*-------------------------------------------------------------*/
/*--- end bzlib_private.h ---*/
/*-------------------------------------------------------------*/

View File

@@ -0,0 +1,720 @@
/*
Copyright (c) 2005-2020 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.
*/
/*-------------------------------------------------------------*/
/*--- Compression machinery (not incl block sorting) ---*/
/*--- compress.cpp ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
The original source for this example:
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
This program, "bzip2", the associated library "libbzip2", and all
documentation, are copyright (C) 1996-2010 Julian R Seward. All
rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
3. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
4. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Julian Seward, jseward@bzip.org
bzip2/libbzip2 version 1.0.6 of 6 September 2010
------------------------------------------------------------------ */
/* CHANGES
0.9.0 -- original version.
0.9.0a/b -- no changes in this file.
0.9.0c -- changed setting of nGroups in sendMTFValues()
so as to do a bit better on small files
*/
#include "bzlib_private.h"
/*---------------------------------------------------*/
/*--- Bit stream I/O ---*/
/*---------------------------------------------------*/
/*---------------------------------------------------*/
void BZ2_bsInitWrite ( EState* s )
{
s->bsLive = 0;
s->bsBuff = 0;
}
/*---------------------------------------------------*/
static
void bsFinishWrite ( EState* s )
{
while (s->bsLive > 0) {
s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
s->numZ++;
s->bsBuff <<= 8;
s->bsLive -= 8;
}
}
/*---------------------------------------------------*/
#define bsNEEDW(nz) \
{ \
while (s->bsLive >= 8) { \
s->zbits[s->numZ] \
= (UChar)(s->bsBuff >> 24); \
s->numZ++; \
s->bsBuff <<= 8; \
s->bsLive -= 8; \
} \
}
/*---------------------------------------------------*/
static
__inline__
void bsW ( EState* s, Int32 n, UInt32 v )
{
bsNEEDW ( n );
s->bsBuff |= (v << (32 - s->bsLive - n));
s->bsLive += n;
}
/*---------------------------------------------------*/
static
void bsPutUInt32 ( EState* s, UInt32 u )
{
bsW ( s, 8, (u >> 24) & 0xffL );
bsW ( s, 8, (u >> 16) & 0xffL );
bsW ( s, 8, (u >> 8) & 0xffL );
bsW ( s, 8, u & 0xffL );
}
/*---------------------------------------------------*/
static
void bsPutUChar ( EState* s, UChar c )
{
bsW( s, 8, (UInt32)c );
}
/*---------------------------------------------------*/
/*--- The back end proper ---*/
/*---------------------------------------------------*/
/*---------------------------------------------------*/
static
void makeMaps_e ( EState* s )
{
Int32 i;
s->nInUse = 0;
for (i = 0; i < 256; i++)
if (s->inUse[i]) {
s->unseqToSeq[i] = s->nInUse;
s->nInUse++;
}
}
/*---------------------------------------------------*/
static
void generateMTFValues ( EState* s )
{
UChar yy[256];
Int32 i, j;
Int32 zPend;
Int32 wr;
Int32 EOB;
/*
After sorting (eg, here),
s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
and
((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
holds the original block data.
The first thing to do is generate the MTF values,
and put them in
((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
Because there are strictly fewer or equal MTF values
than block values, ptr values in this area are overwritten
with MTF values only when they are no longer needed.
The final compressed bitstream is generated into the
area starting at
(UChar*) (&((UChar*)s->arr2)[s->nblock])
These storage aliases are set up in bzCompressInit(),
except for the last one, which is arranged in
compressBlock().
*/
UInt32* ptr = s->ptr;
UChar* block = s->block;
UInt16* mtfv = s->mtfv;
makeMaps_e ( s );
EOB = s->nInUse+1;
for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
wr = 0;
zPend = 0;
for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
for (i = 0; i < s->nblock; i++) {
UChar ll_i;
AssertD ( wr <= i, "generateMTFValues(1)" );
j = ptr[i]-1; if (j < 0) j += s->nblock;
ll_i = s->unseqToSeq[block[j]];
AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
if (yy[0] == ll_i) {
zPend++;
} else {
if (zPend > 0) {
zPend--;
while (True) {
if (zPend & 1) {
mtfv[wr] = BZ_RUNB; wr++;
s->mtfFreq[BZ_RUNB]++;
} else {
mtfv[wr] = BZ_RUNA; wr++;
s->mtfFreq[BZ_RUNA]++;
}
if (zPend < 2) break;
zPend = (zPend - 2) / 2;
};
zPend = 0;
}
{
UChar rtmp;
UChar* ryy_j;
UChar rll_i;
rtmp = yy[1];
yy[1] = yy[0];
ryy_j = &(yy[1]);
rll_i = ll_i;
while ( rll_i != rtmp ) {
UChar rtmp2;
ryy_j++;
rtmp2 = rtmp;
rtmp = *ryy_j;
*ryy_j = rtmp2;
};
yy[0] = rtmp;
j = ryy_j - &(yy[0]);
mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
}
}
}
if (zPend > 0) {
zPend--;
while (True) {
if (zPend & 1) {
mtfv[wr] = BZ_RUNB; wr++;
s->mtfFreq[BZ_RUNB]++;
} else {
mtfv[wr] = BZ_RUNA; wr++;
s->mtfFreq[BZ_RUNA]++;
}
if (zPend < 2) break;
zPend = (zPend - 2) / 2;
};
zPend = 0;
}
mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
s->nMTF = wr;
}
/*---------------------------------------------------*/
#define BZ_LESSER_ICOST 0
#define BZ_GREATER_ICOST 15
static
void sendMTFValues ( EState* s )
{
Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
Int32 nGroups, nBytes;
/*--
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
is a global since the decoder also needs it.
Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
are also globals only used in this proc.
Made global to keep stack frame size small.
--*/
UInt16 cost[BZ_N_GROUPS];
Int32 fave[BZ_N_GROUPS];
UInt16* mtfv = s->mtfv;
if (s->verbosity >= 3)
VPrintf3( " %d in block, %d after MTF & 1-2 coding, "
"%d+2 syms in use\n",
s->nblock, s->nMTF, s->nInUse );
alphaSize = s->nInUse+2;
for (t = 0; t < BZ_N_GROUPS; t++)
for (v = 0; v < alphaSize; v++)
s->len[t][v] = BZ_GREATER_ICOST;
/*--- Decide how many coding tables to use ---*/
AssertH ( s->nMTF > 0, 3001 );
if (s->nMTF < 200) nGroups = 2; else
if (s->nMTF < 600) nGroups = 3; else
if (s->nMTF < 1200) nGroups = 4; else
if (s->nMTF < 2400) nGroups = 5; else
nGroups = 6;
/*--- Generate an initial set of coding tables ---*/
{
Int32 nPart, remF, tFreq, aFreq;
nPart = nGroups;
remF = s->nMTF;
gs = 0;
while (nPart > 0) {
tFreq = remF / nPart;
ge = gs-1;
aFreq = 0;
while (aFreq < tFreq && ge < alphaSize-1) {
ge++;
aFreq += s->mtfFreq[ge];
}
if (ge > gs
&& nPart != nGroups && nPart != 1
&& ((nGroups-nPart) % 2 == 1)) {
aFreq -= s->mtfFreq[ge];
ge--;
}
if (s->verbosity >= 3)
VPrintf5( " initial group %d, [%d .. %d], "
"has %d syms (%4.1f%%)\n",
nPart, gs, ge, aFreq,
(100.0 * (float)aFreq) / (float)(s->nMTF) );
for (v = 0; v < alphaSize; v++)
if (v >= gs && v <= ge)
s->len[nPart-1][v] = BZ_LESSER_ICOST; else
s->len[nPart-1][v] = BZ_GREATER_ICOST;
nPart--;
gs = ge+1;
remF -= aFreq;
}
}
/*---
Iterate up to BZ_N_ITERS times to improve the tables.
---*/
for (iter = 0; iter < BZ_N_ITERS; iter++) {
for (t = 0; t < nGroups; t++) fave[t] = 0;
for (t = 0; t < nGroups; t++)
for (v = 0; v < alphaSize; v++)
s->rfreq[t][v] = 0;
/*---
Set up an auxiliary length table which is used to fast-track
the common case (nGroups == 6).
---*/
if (nGroups == 6) {
for (v = 0; v < alphaSize; v++) {
s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
}
}
nSelectors = 0;
totc = 0;
gs = 0;
while (True) {
/*--- Set group start & end marks. --*/
if (gs >= s->nMTF) break;
ge = gs + BZ_G_SIZE - 1;
if (ge >= s->nMTF) ge = s->nMTF-1;
/*--
Calculate the cost of this group as coded
by each of the coding tables.
--*/
for (t = 0; t < nGroups; t++) cost[t] = 0;
if (nGroups == 6 && 50 == ge-gs+1) {
/*--- fast track the common case ---*/
UInt32 cost01, cost23, cost45;
UInt16 icv;
cost01 = cost23 = cost45 = 0;
# define BZ_ITER(nn) \
icv = mtfv[gs+(nn)]; \
cost01 += s->len_pack[icv][0]; \
cost23 += s->len_pack[icv][1]; \
cost45 += s->len_pack[icv][2]; \
BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
# undef BZ_ITER
cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
} else {
/*--- slow version which correctly handles all situations ---*/
for (i = gs; i <= ge; i++) {
UInt16 icv = mtfv[i];
for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
}
}
/*--
Find the coding table which is best for this group,
and record its identity in the selector table.
--*/
bc = 999999999; bt = -1;
for (t = 0; t < nGroups; t++)
if (cost[t] < bc) { bc = cost[t]; bt = t; };
totc += bc;
fave[bt]++;
s->selector[nSelectors] = bt;
nSelectors++;
/*--
Increment the symbol frequencies for the selected table.
--*/
if (nGroups == 6 && 50 == ge-gs+1) {
/*--- fast track the common case ---*/
# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
# undef BZ_ITUR
} else {
/*--- slow version which correctly handles all situations ---*/
for (i = gs; i <= ge; i++)
s->rfreq[bt][ mtfv[i] ]++;
}
gs = ge+1;
}
if (s->verbosity >= 3) {
VPrintf2 ( " pass %d: size is %d, grp uses are ",
iter+1, totc/8 );
for (t = 0; t < nGroups; t++)
VPrintf1 ( "%d ", fave[t] );
VPrintf0 ( "\n" );
}
/*--
Recompute the tables based on the accumulated frequencies.
--*/
/* maxLen was changed from 20 to 17 in bzip2-1.0.3. See
comment in huffman.c for details. */
for (t = 0; t < nGroups; t++)
BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
alphaSize, 17 /*20*/ );
}
AssertH( nGroups < 8, 3002 );
AssertH( nSelectors < 32768 &&
nSelectors <= (2 + (900000 / BZ_G_SIZE)),
3003 );
/*--- Compute MTF values for the selectors. ---*/
{
UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
for (i = 0; i < nGroups; i++) pos[i] = i;
for (i = 0; i < nSelectors; i++) {
ll_i = s->selector[i];
j = 0;
tmp = pos[j];
while ( ll_i != tmp ) {
j++;
tmp2 = tmp;
tmp = pos[j];
pos[j] = tmp2;
};
pos[0] = tmp;
s->selectorMtf[i] = j;
}
};
/*--- Assign actual codes for the tables. --*/
for (t = 0; t < nGroups; t++) {
minLen = 32;
maxLen = 0;
for (i = 0; i < alphaSize; i++) {
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
if (s->len[t][i] < minLen) minLen = s->len[t][i];
}
AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
AssertH ( !(minLen < 1), 3005 );
BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
minLen, maxLen, alphaSize );
}
/*--- Transmit the mapping table. ---*/
{
Bool inUse16[16];
for (i = 0; i < 16; i++) {
inUse16[i] = False;
for (j = 0; j < 16; j++)
if (s->inUse[i * 16 + j]) inUse16[i] = True;
}
nBytes = s->numZ;
for (i = 0; i < 16; i++)
if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
for (i = 0; i < 16; i++)
if (inUse16[i])
for (j = 0; j < 16; j++) {
if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
}
if (s->verbosity >= 3)
VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes );
}
/*--- Now the selectors. ---*/
nBytes = s->numZ;
bsW ( s, 3, nGroups );
bsW ( s, 15, nSelectors );
for (i = 0; i < nSelectors; i++) {
for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
bsW(s,1,0);
}
if (s->verbosity >= 3)
VPrintf1( "selectors %d, ", s->numZ-nBytes );
/*--- Now the coding tables. ---*/
nBytes = s->numZ;
for (t = 0; t < nGroups; t++) {
Int32 curr = s->len[t][0];
bsW ( s, 5, curr );
for (i = 0; i < alphaSize; i++) {
while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
bsW ( s, 1, 0 );
}
}
if (s->verbosity >= 3)
VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
/*--- And finally, the block data proper ---*/
nBytes = s->numZ;
selCtr = 0;
gs = 0;
while (True) {
if (gs >= s->nMTF) break;
ge = gs + BZ_G_SIZE - 1;
if (ge >= s->nMTF) ge = s->nMTF-1;
AssertH ( s->selector[selCtr] < nGroups, 3006 );
if (nGroups == 6 && 50 == ge-gs+1) {
/*--- fast track the common case ---*/
UInt16 mtfv_i;
UChar* s_len_sel_selCtr
= &(s->len[s->selector[selCtr]][0]);
Int32* s_code_sel_selCtr
= &(s->code[s->selector[selCtr]][0]);
# define BZ_ITAH(nn) \
mtfv_i = mtfv[gs+(nn)]; \
bsW ( s, \
s_len_sel_selCtr[mtfv_i], \
s_code_sel_selCtr[mtfv_i] )
BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
# undef BZ_ITAH
} else {
/*--- slow version which correctly handles all situations ---*/
for (i = gs; i <= ge; i++) {
bsW ( s,
s->len [s->selector[selCtr]] [mtfv[i]],
s->code [s->selector[selCtr]] [mtfv[i]] );
}
}
gs = ge+1;
selCtr++;
}
AssertH( selCtr == nSelectors, 3007 );
if (s->verbosity >= 3)
VPrintf1( "codes %d\n", s->numZ-nBytes );
}
/*---------------------------------------------------*/
void BZ2_compressBlock ( EState* s, Bool is_last_block )
{
if (s->nblock > 0) {
BZ_FINALISE_CRC ( s->blockCRC );
s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
s->combinedCRC ^= s->blockCRC;
if (s->blockNo > 1) s->numZ = 0;
if (s->verbosity >= 2)
VPrintf4( " block %d: crc = 0x%08x, "
"combined CRC = 0x%08x, size = %d\n",
s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
BZ2_blockSort ( s );
}
s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
/*-- If this is the first block, create the stream header. --*/
if (s->blockNo == 1) {
BZ2_bsInitWrite ( s );
bsPutUChar ( s, BZ_HDR_B );
bsPutUChar ( s, BZ_HDR_Z );
bsPutUChar ( s, BZ_HDR_h );
bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
}
if (s->nblock > 0) {
bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
/*-- Now the block's CRC, so it is in a known place. --*/
bsPutUInt32 ( s, s->blockCRC );
/*--
Now a single bit indicating (non-)randomisation.
As of version 0.9.5, we use a better sorting algorithm
which makes randomisation unnecessary. So always set
the randomised bit to 'no'. Of course, the decoder
still needs to be able to handle randomised blocks
so as to maintain backwards compatibility with
older versions of bzip2.
--*/
bsW(s,1,0);
bsW ( s, 24, s->origPtr );
generateMTFValues ( s );
sendMTFValues ( s );
}
/*-- If this is the last block, add the stream trailer. --*/
if (is_last_block) {
bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
bsPutUInt32 ( s, s->combinedCRC );
if (s->verbosity >= 2)
VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC );
bsFinishWrite ( s );
}
}
/*-------------------------------------------------------------*/
/*--- end compress.c ---*/
/*-------------------------------------------------------------*/

View File

@@ -0,0 +1,152 @@
/*
Copyright (c) 2005-2020 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.
*/
/*-------------------------------------------------------------*/
/*--- Table for doing CRCs ---*/
/*--- crctable.cpp ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
The original source for this example:
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
This program, "bzip2", the associated library "libbzip2", and all
documentation, are copyright (C) 1996-2010 Julian R Seward. All
rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
3. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
4. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Julian Seward, jseward@bzip.org
bzip2/libbzip2 version 1.0.6 of 6 September 2010
------------------------------------------------------------------ */
#include "bzlib_private.h"
/*--
I think this is an implementation of the AUTODIN-II,
Ethernet & FDDI 32-bit CRC standard. Vaguely derived
from code by Rob Warnock, in Section 51 of the
comp.compression FAQ.
--*/
UInt32 BZ2_crc32Table[256] = {
/*-- Ugly, innit? --*/
0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
};
/*-------------------------------------------------------------*/
/*--- end crctable.c ---*/
/*-------------------------------------------------------------*/

View File

@@ -0,0 +1,694 @@
/*
Copyright (c) 2005-2020 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.
*/
/*-------------------------------------------------------------*/
/*--- Decompression machinery ---*/
/*--- decompress.cpp ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
The original source for this example:
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
This program, "bzip2", the associated library "libbzip2", and all
documentation, are copyright (C) 1996-2010 Julian R Seward. All
rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
3. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
4. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Julian Seward, jseward@bzip.org
bzip2/libbzip2 version 1.0.6 of 6 September 2010
------------------------------------------------------------------ */
#include "bzlib_private.h"
/*---------------------------------------------------*/
static
void makeMaps_d ( DState* s )
{
Int32 i;
s->nInUse = 0;
for (i = 0; i < 256; i++)
if (s->inUse[i]) {
s->seqToUnseq[s->nInUse] = i;
s->nInUse++;
}
}
/*---------------------------------------------------*/
#define RETURN(rrr) \
{ retVal = rrr; goto save_state_and_return; };
#define GET_BITS(lll,vvv,nnn) \
case lll: s->state = lll; \
while (True) { \
if (s->bsLive >= nnn) { \
UInt32 v; \
v = (s->bsBuff >> \
(s->bsLive-nnn)) & ((1 << nnn)-1); \
s->bsLive -= nnn; \
vvv = v; \
break; \
} \
if (s->strm->avail_in == 0) RETURN(BZ_OK); \
s->bsBuff \
= (s->bsBuff << 8) | \
((UInt32) \
(*((UChar*)(s->strm->next_in)))); \
s->bsLive += 8; \
s->strm->next_in++; \
s->strm->avail_in--; \
s->strm->total_in_lo32++; \
if (s->strm->total_in_lo32 == 0) \
s->strm->total_in_hi32++; \
}
#define GET_UCHAR(lll,uuu) \
GET_BITS(lll,uuu,8)
#define GET_BIT(lll,uuu) \
GET_BITS(lll,uuu,1)
/*---------------------------------------------------*/
#define GET_MTF_VAL(label1,label2,lval) \
{ \
if (groupPos == 0) { \
groupNo++; \
if (groupNo >= nSelectors) \
RETURN(BZ_DATA_ERROR); \
groupPos = BZ_G_SIZE; \
gSel = s->selector[groupNo]; \
gMinlen = s->minLens[gSel]; \
gLimit = &(s->limit[gSel][0]); \
gPerm = &(s->perm[gSel][0]); \
gBase = &(s->base[gSel][0]); \
} \
groupPos--; \
zn = gMinlen; \
GET_BITS(label1, zvec, zn); \
while (1) { \
if (zn > 20 /* the longest code */) \
RETURN(BZ_DATA_ERROR); \
if (zvec <= gLimit[zn]) break; \
zn++; \
GET_BIT(label2, zj); \
zvec = (zvec << 1) | zj; \
}; \
if (zvec - gBase[zn] < 0 \
|| zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
RETURN(BZ_DATA_ERROR); \
lval = gPerm[zvec - gBase[zn]]; \
}
/*---------------------------------------------------*/
Int32 BZ2_decompress ( DState* s )
{
UChar uc;
Int32 retVal;
Int32 minLen, maxLen;
bz_stream* strm = s->strm;
/* stuff that needs to be saved/restored */
Int32 i;
Int32 j;
Int32 t;
Int32 alphaSize;
Int32 nGroups;
Int32 nSelectors;
Int32 EOB;
Int32 groupNo;
Int32 groupPos;
Int32 nextSym;
Int32 nblockMAX;
Int32 nblock;
Int32 es;
Int32 N;
Int32 curr;
Int32 zt;
Int32 zn;
Int32 zvec;
Int32 zj;
Int32 gSel;
Int32 gMinlen;
Int32* gLimit;
Int32* gBase;
Int32* gPerm;
if (s->state == BZ_X_MAGIC_1) {
/*initialise the save area*/
s->save_i = 0;
s->save_j = 0;
s->save_t = 0;
s->save_alphaSize = 0;
s->save_nGroups = 0;
s->save_nSelectors = 0;
s->save_EOB = 0;
s->save_groupNo = 0;
s->save_groupPos = 0;
s->save_nextSym = 0;
s->save_nblockMAX = 0;
s->save_nblock = 0;
s->save_es = 0;
s->save_N = 0;
s->save_curr = 0;
s->save_zt = 0;
s->save_zn = 0;
s->save_zvec = 0;
s->save_zj = 0;
s->save_gSel = 0;
s->save_gMinlen = 0;
s->save_gLimit = NULL;
s->save_gBase = NULL;
s->save_gPerm = NULL;
}
/*restore from the save area*/
i = s->save_i;
j = s->save_j;
t = s->save_t;
alphaSize = s->save_alphaSize;
nGroups = s->save_nGroups;
nSelectors = s->save_nSelectors;
EOB = s->save_EOB;
groupNo = s->save_groupNo;
groupPos = s->save_groupPos;
nextSym = s->save_nextSym;
nblockMAX = s->save_nblockMAX;
nblock = s->save_nblock;
es = s->save_es;
N = s->save_N;
curr = s->save_curr;
zt = s->save_zt;
zn = s->save_zn;
zvec = s->save_zvec;
zj = s->save_zj;
gSel = s->save_gSel;
gMinlen = s->save_gMinlen;
gLimit = s->save_gLimit;
gBase = s->save_gBase;
gPerm = s->save_gPerm;
retVal = BZ_OK;
switch (s->state) {
GET_UCHAR(BZ_X_MAGIC_1, uc);
if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
GET_UCHAR(BZ_X_MAGIC_2, uc);
if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
GET_UCHAR(BZ_X_MAGIC_3, uc)
if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
if (s->blockSize100k < (BZ_HDR_0 + 1) ||
s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
s->blockSize100k -= BZ_HDR_0;
if (s->smallDecompress) {
s->ll16 = (UInt16*)BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
s->ll4 = (UChar*)BZALLOC(
((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
);
if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
} else {
s->tt = (UInt32*)BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
}
GET_UCHAR(BZ_X_BLKHDR_1, uc);
if (uc == 0x17) goto endhdr_2;
if (uc != 0x31) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_2, uc);
if (uc != 0x41) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_3, uc);
if (uc != 0x59) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_4, uc);
if (uc != 0x26) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_5, uc);
if (uc != 0x53) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_BLKHDR_6, uc);
if (uc != 0x59) RETURN(BZ_DATA_ERROR);
s->currBlockNo++;
if (s->verbosity >= 2)
VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
s->storedBlockCRC = 0;
GET_UCHAR(BZ_X_BCRC_1, uc);
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_BCRC_2, uc);
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_BCRC_3, uc);
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_BCRC_4, uc);
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
s->origPtr = 0;
GET_UCHAR(BZ_X_ORIGPTR_1, uc);
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
GET_UCHAR(BZ_X_ORIGPTR_2, uc);
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
GET_UCHAR(BZ_X_ORIGPTR_3, uc);
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
if (s->origPtr < 0)
RETURN(BZ_DATA_ERROR);
if (s->origPtr > 10 + 100000*s->blockSize100k)
RETURN(BZ_DATA_ERROR);
/*--- Receive the mapping table ---*/
for (i = 0; i < 16; i++) {
GET_BIT(BZ_X_MAPPING_1, uc);
if (uc == 1)
s->inUse16[i] = True; else
s->inUse16[i] = False;
}
for (i = 0; i < 256; i++) s->inUse[i] = False;
for (i = 0; i < 16; i++)
if (s->inUse16[i])
for (j = 0; j < 16; j++) {
GET_BIT(BZ_X_MAPPING_2, uc);
if (uc == 1) s->inUse[i * 16 + j] = True;
}
makeMaps_d ( s );
if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
alphaSize = s->nInUse+2;
/*--- Now the selectors ---*/
GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
for (i = 0; i < nSelectors; i++) {
j = 0;
while (True) {
GET_BIT(BZ_X_SELECTOR_3, uc);
if (uc == 0) break;
j++;
if (j >= nGroups) RETURN(BZ_DATA_ERROR);
}
s->selectorMtf[i] = j;
}
/*--- Undo the MTF values for the selectors. ---*/
{
UChar pos[BZ_N_GROUPS], tmp, v;
for (v = 0; v < nGroups; v++) pos[v] = v;
for (i = 0; i < nSelectors; i++) {
v = s->selectorMtf[i];
tmp = pos[v];
while (v > 0) { pos[v] = pos[v-1]; v--; }
pos[0] = tmp;
s->selector[i] = tmp;
}
}
/*--- Now the coding tables ---*/
for (t = 0; t < nGroups; t++) {
GET_BITS(BZ_X_CODING_1, curr, 5);
for (i = 0; i < alphaSize; i++) {
while (True) {
if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
GET_BIT(BZ_X_CODING_2, uc);
if (uc == 0) break;
GET_BIT(BZ_X_CODING_3, uc);
if (uc == 0) curr++; else curr--;
}
s->len[t][i] = curr;
}
}
/*--- Create the Huffman decoding tables ---*/
for (t = 0; t < nGroups; t++) {
minLen = 32;
maxLen = 0;
for (i = 0; i < alphaSize; i++) {
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
if (s->len[t][i] < minLen) minLen = s->len[t][i];
}
BZ2_hbCreateDecodeTables (
&(s->limit[t][0]),
&(s->base[t][0]),
&(s->perm[t][0]),
&(s->len[t][0]),
minLen, maxLen, alphaSize
);
s->minLens[t] = minLen;
}
/*--- Now the MTF values ---*/
EOB = s->nInUse+1;
nblockMAX = 100000 * s->blockSize100k;
groupNo = -1;
groupPos = 0;
for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
/*-- MTF init --*/
{
Int32 ii, jj, kk;
kk = MTFA_SIZE-1;
for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
kk--;
}
s->mtfbase[ii] = kk + 1;
}
}
/*-- end MTF init --*/
nblock = 0;
GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
while (True) {
if (nextSym == EOB) break;
if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
es = -1;
N = 1;
do {
/* Check that N doesn't get too big, so that es doesn't
go negative. The maximum value that can be
RUNA/RUNB encoded is equal to the block size (post
the initial RLE), viz, 900k, so bounding N at 2
million should guard against overflow without
rejecting any legitimate inputs. */
if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
if (nextSym == BZ_RUNB) es = es + (1+1) * N;
N = N * 2;
GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
}
while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
es++;
uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
s->unzftab[uc] += es;
if (s->smallDecompress)
while (es > 0) {
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
s->ll16[nblock] = (UInt16)uc;
nblock++;
es--;
}
else
while (es > 0) {
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
s->tt[nblock] = (UInt32)uc;
nblock++;
es--;
};
continue;
} else {
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
/*-- uc = MTF ( nextSym-1 ) --*/
{
Int32 ii, jj, kk, pp, lno, off;
UInt32 nn;
nn = (UInt32)(nextSym - 1);
if (nn < MTFL_SIZE) {
/* avoid general-case expense */
pp = s->mtfbase[0];
uc = s->mtfa[pp+nn];
while (nn > 3) {
Int32 z = pp+nn;
s->mtfa[(z) ] = s->mtfa[(z)-1];
s->mtfa[(z)-1] = s->mtfa[(z)-2];
s->mtfa[(z)-2] = s->mtfa[(z)-3];
s->mtfa[(z)-3] = s->mtfa[(z)-4];
nn -= 4;
}
while (nn > 0) {
s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
};
s->mtfa[pp] = uc;
} else {
/* general case */
lno = nn / MTFL_SIZE;
off = nn % MTFL_SIZE;
pp = s->mtfbase[lno] + off;
uc = s->mtfa[pp];
while (pp > s->mtfbase[lno]) {
s->mtfa[pp] = s->mtfa[pp-1]; pp--;
};
s->mtfbase[lno]++;
while (lno > 0) {
s->mtfbase[lno]--;
s->mtfa[s->mtfbase[lno]]
= s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
lno--;
}
s->mtfbase[0]--;
s->mtfa[s->mtfbase[0]] = uc;
if (s->mtfbase[0] == 0) {
kk = MTFA_SIZE-1;
for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
kk--;
}
s->mtfbase[ii] = kk + 1;
}
}
}
}
/*-- end uc = MTF ( nextSym-1 ) --*/
s->unzftab[s->seqToUnseq[uc]]++;
if (s->smallDecompress)
s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
nblock++;
GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
continue;
}
}
/* Now we know what nblock is, we can do a better sanity
check on s->origPtr.
*/
if (s->origPtr < 0 || s->origPtr >= nblock)
RETURN(BZ_DATA_ERROR);
/*-- Set up cftab to facilitate generation of T^(-1) --*/
/* Check: unzftab entries in range. */
for (i = 0; i <= 255; i++) {
if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
RETURN(BZ_DATA_ERROR);
}
/* Actually generate cftab. */
s->cftab[0] = 0;
for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
/* Check: cftab entries in range. */
for (i = 0; i <= 256; i++) {
if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
/* s->cftab[i] can legitimately be == nblock */
RETURN(BZ_DATA_ERROR);
}
}
/* Check: cftab entries non-descending. */
for (i = 1; i <= 256; i++) {
if (s->cftab[i-1] > s->cftab[i]) {
RETURN(BZ_DATA_ERROR);
}
}
s->state_out_len = 0;
s->state_out_ch = 0;
BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
s->state = BZ_X_OUTPUT;
if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
if (s->smallDecompress) {
/*-- Make a copy of cftab, used in generation of T --*/
for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
/*-- compute the T vector --*/
for (i = 0; i < nblock; i++) {
uc = (UChar)(s->ll16[i]);
SET_LL(i, s->cftabCopy[uc]);
s->cftabCopy[uc]++;
}
/*-- Compute T^(-1) by pointer reversal on T --*/
i = s->origPtr;
j = GET_LL(i);
do {
Int32 tmp = GET_LL(j);
SET_LL(j, i);
i = j;
j = tmp;
}
while (i != s->origPtr);
s->tPos = s->origPtr;
s->nblock_used = 0;
if (s->blockRandomised) {
BZ_RAND_INIT_MASK;
BZ_GET_SMALL(s->k0); s->nblock_used++;
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
} else {
BZ_GET_SMALL(s->k0); s->nblock_used++;
}
} else {
/*-- compute the T^(-1) vector --*/
for (i = 0; i < nblock; i++) {
uc = (UChar)(s->tt[i] & 0xff);
s->tt[s->cftab[uc]] |= (i << 8);
s->cftab[uc]++;
}
s->tPos = s->tt[s->origPtr] >> 8;
s->nblock_used = 0;
if (s->blockRandomised) {
BZ_RAND_INIT_MASK;
BZ_GET_FAST(s->k0); s->nblock_used++;
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
} else {
BZ_GET_FAST(s->k0); s->nblock_used++;
}
}
RETURN(BZ_OK);
endhdr_2:
GET_UCHAR(BZ_X_ENDHDR_2, uc);
if (uc != 0x72) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_ENDHDR_3, uc);
if (uc != 0x45) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_ENDHDR_4, uc);
if (uc != 0x38) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_ENDHDR_5, uc);
if (uc != 0x50) RETURN(BZ_DATA_ERROR);
GET_UCHAR(BZ_X_ENDHDR_6, uc);
if (uc != 0x90) RETURN(BZ_DATA_ERROR);
s->storedCombinedCRC = 0;
GET_UCHAR(BZ_X_CCRC_1, uc);
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_CCRC_2, uc);
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_CCRC_3, uc);
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
GET_UCHAR(BZ_X_CCRC_4, uc);
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
s->state = BZ_X_IDLE;
RETURN(BZ_STREAM_END);
default: AssertH ( False, 4001 );
}
AssertH ( False, 4002 );
save_state_and_return:
s->save_i = i;
s->save_j = j;
s->save_t = t;
s->save_alphaSize = alphaSize;
s->save_nGroups = nGroups;
s->save_nSelectors = nSelectors;
s->save_EOB = EOB;
s->save_groupNo = groupNo;
s->save_groupPos = groupPos;
s->save_nextSym = nextSym;
s->save_nblockMAX = nblockMAX;
s->save_nblock = nblock;
s->save_es = es;
s->save_N = N;
s->save_curr = curr;
s->save_zt = zt;
s->save_zn = zn;
s->save_zvec = zvec;
s->save_zj = zj;
s->save_gSel = gSel;
s->save_gMinlen = gMinlen;
s->save_gLimit = gLimit;
s->save_gBase = gBase;
s->save_gPerm = gPerm;
return retVal;
}
/*-------------------------------------------------------------*/
/*--- end decompress.c ---*/
/*-------------------------------------------------------------*/

View File

@@ -0,0 +1,498 @@
/*
Copyright (c) 2005-2020 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 TBB_PREVIEW_FLOW_GRAPH_FEATURES 1
#include "tbb/tbb_config.h"
#include "../../common/utility/utility.h"
#if __TBB_PREVIEW_ASYNC_MSG && __TBB_CPP11_LAMBDAS_PRESENT
#include <iostream>
#include <fstream>
#include <string>
#include <memory>
#include <queue>
#include <thread>
#include "bzlib.h"
#include "tbb/flow_graph.h"
#include "tbb/tick_count.h"
#include "tbb/concurrent_queue.h"
// TODO: change memory allocation/deallocation to be managed in constructor/destructor
struct Buffer {
size_t len;
char* b;
};
struct BufferMsg {
BufferMsg() {}
BufferMsg(Buffer& inputBuffer, Buffer& outputBuffer, size_t seqId, bool isLast = false)
: inputBuffer(inputBuffer), outputBuffer(outputBuffer), seqId(seqId), isLast(isLast) {}
static BufferMsg createBufferMsg(size_t seqId, size_t chunkSize) {
Buffer inputBuffer;
inputBuffer.b = new char[chunkSize];
inputBuffer.len = chunkSize;
Buffer outputBuffer;
size_t compressedChunkSize = chunkSize * 1.01 + 600; // compression overhead
outputBuffer.b = new char[compressedChunkSize];
outputBuffer.len = compressedChunkSize;
return BufferMsg(inputBuffer, outputBuffer, seqId);
}
static void destroyBufferMsg(const BufferMsg& destroyMsg) {
delete[] destroyMsg.inputBuffer.b;
delete[] destroyMsg.outputBuffer.b;
}
void markLast(size_t lastId) {
isLast = true;
seqId = lastId;
}
size_t seqId;
Buffer inputBuffer;
Buffer outputBuffer;
bool isLast;
};
class BufferCompressor {
public:
BufferCompressor(int blockSizeIn100KB) : m_blockSize(blockSizeIn100KB) {}
BufferMsg operator()(BufferMsg buffer) const {
if (!buffer.isLast) {
unsigned int outSize = buffer.outputBuffer.len;
BZ2_bzBuffToBuffCompress(buffer.outputBuffer.b, &outSize,
buffer.inputBuffer.b, buffer.inputBuffer.len,
m_blockSize, 0, 30);
buffer.outputBuffer.len = outSize;
}
return buffer;
}
private:
int m_blockSize;
};
class IOOperations {
public:
IOOperations(std::ifstream& inputStream, std::ofstream& outputStream, size_t chunkSize)
: m_inputStream(inputStream), m_outputStream(outputStream), m_chunkSize(chunkSize), m_chunksRead(0) {}
void readChunk(Buffer& buffer) {
m_inputStream.read(buffer.b, m_chunkSize);
buffer.len = static_cast<size_t>(m_inputStream.gcount());
m_chunksRead++;
}
void writeChunk(const Buffer& buffer) {
m_outputStream.write(buffer.b, buffer.len);
}
size_t chunksRead() const {
return m_chunksRead;
}
size_t chunkSize() const {
return m_chunkSize;
}
bool hasDataToRead() const {
return m_inputStream.is_open() && !m_inputStream.eof();
}
private:
std::ifstream& m_inputStream;
std::ofstream& m_outputStream;
size_t m_chunkSize;
size_t m_chunksRead;
};
//-----------------------------------------------------------------------------------------------------------------------
//---------------------------------------Compression example based on async_node-----------------------------------------
//-----------------------------------------------------------------------------------------------------------------------
typedef tbb::flow::async_node< tbb::flow::continue_msg, BufferMsg > async_file_reader_node;
typedef tbb::flow::async_node< BufferMsg, tbb::flow::continue_msg > async_file_writer_node;
class AsyncNodeActivity {
public:
AsyncNodeActivity(IOOperations& io)
: m_io(io), m_fileWriterThread(&AsyncNodeActivity::writingLoop, this) {}
~AsyncNodeActivity() {
m_fileReaderThread.join();
m_fileWriterThread.join();
}
void submitRead(async_file_reader_node::gateway_type& gateway) {
gateway.reserve_wait();
std::thread(&AsyncNodeActivity::readingLoop, this, std::ref(gateway)).swap(m_fileReaderThread);
}
void submitWrite(const BufferMsg& bufferMsg) {
m_writeQueue.push(bufferMsg);
}
private:
void readingLoop(async_file_reader_node::gateway_type& gateway) {
while (m_io.hasDataToRead()) {
BufferMsg bufferMsg = BufferMsg::createBufferMsg(m_io.chunksRead(), m_io.chunkSize());
m_io.readChunk(bufferMsg.inputBuffer);
gateway.try_put(bufferMsg);
}
sendLastMessage(gateway);
gateway.release_wait();
}
void writingLoop() {
BufferMsg buffer;
m_writeQueue.pop(buffer);
while (!buffer.isLast) {
m_io.writeChunk(buffer.outputBuffer);
m_writeQueue.pop(buffer);
}
}
void sendLastMessage(async_file_reader_node::gateway_type& gateway) {
BufferMsg lastMsg;
lastMsg.markLast(m_io.chunksRead());
gateway.try_put(lastMsg);
}
IOOperations& m_io;
tbb::concurrent_bounded_queue< BufferMsg > m_writeQueue;
std::thread m_fileReaderThread;
std::thread m_fileWriterThread;
};
void fgCompressionAsyncNode(IOOperations& io, int blockSizeIn100KB) {
tbb::flow::graph g;
AsyncNodeActivity asyncNodeActivity(io);
async_file_reader_node file_reader(g, tbb::flow::unlimited, [&asyncNodeActivity](const tbb::flow::continue_msg& msg, async_file_reader_node::gateway_type& gateway) {
asyncNodeActivity.submitRead(gateway);
});
tbb::flow::function_node< BufferMsg, BufferMsg > compressor(g, tbb::flow::unlimited, BufferCompressor(blockSizeIn100KB));
tbb::flow::sequencer_node< BufferMsg > ordering(g, [](const BufferMsg& bufferMsg)->size_t {
return bufferMsg.seqId;
});
// The node is serial to preserve the right order of buffers set by the preceding sequencer_node
async_file_writer_node output_writer(g, tbb::flow::serial, [&asyncNodeActivity](const BufferMsg& bufferMsg, async_file_writer_node::gateway_type& gateway) {
asyncNodeActivity.submitWrite(bufferMsg);
});
make_edge(file_reader, compressor);
make_edge(compressor, ordering);
make_edge(ordering, output_writer);
file_reader.try_put(tbb::flow::continue_msg());
g.wait_for_all();
}
//-----------------------------------------------------------------------------------------------------------------------
//------------------------------------------Compression example based on async_msg---------------------------------------
//-----------------------------------------------------------------------------------------------------------------------
typedef tbb::flow::async_msg< BufferMsg > async_msg_type;
class AsyncMsgActivity {
public:
AsyncMsgActivity(tbb::flow::graph& g, IOOperations& io)
: m_io(io), m_graph(g), m_fileReaderThread(&AsyncMsgActivity::readingLoop, this),
m_fileWriterThread(&AsyncMsgActivity::writingLoop, this)
{
// Graph synchronization starts here and ends
// when the last buffer was written in "writing thread"
m_graph.increment_wait_count();
}
~AsyncMsgActivity() {
m_fileReaderThread.join();
m_fileWriterThread.join();
// Lets release resources that async
// activity and graph were acquired
freeBuffers();
}
async_msg_type submitRead(BufferMsg& bufferMsg) {
async_msg_type msg;
work_type readWork = { bufferMsg, msg };
m_readQueue.push(readWork);
return msg;
}
async_msg_type submitWrite(const BufferMsg& bufferMsg) {
async_msg_type msg;
work_type writeWork = { bufferMsg, msg };
m_writeQueue.push(writeWork);
return msg;
}
private:
struct work_type {
BufferMsg bufferMsg;
async_msg_type msg;
};
void readingLoop() {
work_type readWork;
m_readQueue.pop(readWork);
// Reading thread waits for buffers to be received
// (the graph reuses limited number of buffers)
// and reads the file while there is something to read
while (m_io.hasDataToRead()) {
readWork.bufferMsg.seqId = m_io.chunksRead();
m_io.readChunk(readWork.bufferMsg.inputBuffer);
readWork.msg.set(readWork.bufferMsg);
m_readQueue.pop(readWork);
}
// Pass message with an end flag to the graph
sendLastMessage(readWork);
}
void sendLastMessage(work_type& work) {
work.bufferMsg.markLast(m_io.chunksRead());
work.msg.set(work.bufferMsg);
}
void writingLoop() {
work_type writeWork;
m_writeQueue.pop(writeWork);
// Writing thread writes all buffers that it gets
// and reuses them. At the end all reusing buffers
// is stored in read queue
while (!writeWork.bufferMsg.isLast) {
m_io.writeChunk(writeWork.bufferMsg.outputBuffer);
writeWork.msg.set(writeWork.bufferMsg);
m_writeQueue.pop(writeWork);
}
// Store last message to the reading queue to free resources later
writeWork.msg.set(writeWork.bufferMsg);
// After all buffers have been written
// the synchronization ends
m_graph.decrement_wait_count();
}
void freeBuffers() {
int buffersNumber = m_readQueue.size();
for (int i = 0; i < buffersNumber; i++) {
work_type workToDelete;
m_readQueue.pop(workToDelete);
BufferMsg::destroyBufferMsg(workToDelete.bufferMsg);
}
}
IOOperations& m_io;
tbb::flow::graph& m_graph;
tbb::concurrent_bounded_queue< work_type > m_writeQueue;
tbb::concurrent_bounded_queue< work_type > m_readQueue;
std::thread m_fileReaderThread;
std::thread m_fileWriterThread;
};
void fgCompressionAsyncMsg(IOOperations& io, int blockSizeIn100KB, size_t memoryLimitIn1MB) {
// Memory limit sets the number of buffers that can be reused
int buffersNumber = memoryLimitIn1MB * 1000 * 1024 / io.chunkSize();
tbb::flow::graph g;
AsyncMsgActivity asyncMsgActivity(g, io);
tbb::flow::function_node< BufferMsg, async_msg_type > file_reader(g, tbb::flow::unlimited, [&asyncMsgActivity](BufferMsg bufferMsg) -> async_msg_type {
return asyncMsgActivity.submitRead(bufferMsg);
});
tbb::flow::function_node< BufferMsg, BufferMsg > compressor(g, tbb::flow::unlimited, BufferCompressor(blockSizeIn100KB));
tbb::flow::sequencer_node< BufferMsg > ordering(g, [](const BufferMsg& bufferMsg) -> size_t {
return bufferMsg.seqId;
});
// The node is serial to preserve the right order of buffers set by the preceding sequencer_node
tbb::flow::function_node< BufferMsg, async_msg_type > output_writer(g, tbb::flow::serial, [&asyncMsgActivity](const BufferMsg& bufferMsg) -> async_msg_type {
return asyncMsgActivity.submitWrite(bufferMsg);
});
make_edge(file_reader, compressor);
make_edge(compressor, ordering);
make_edge(ordering, output_writer);
make_edge(output_writer, file_reader);
// Creating buffers to be reused in read/compress/write graph loop
for (int i = 0; i < buffersNumber; i++) {
BufferMsg reuseBufferMsg = BufferMsg::createBufferMsg(0, io.chunkSize());
file_reader.try_put(reuseBufferMsg);
}
g.wait_for_all();
}
//-----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------Simple compression example------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------
void fgCompression(IOOperations& io, int blockSizeIn100KB) {
tbb::flow::graph g;
tbb::flow::input_node< BufferMsg > file_reader(g, [&io](BufferMsg& bufferMsg)->bool {
if (io.hasDataToRead()) {
bufferMsg = BufferMsg::createBufferMsg(io.chunksRead(), io.chunkSize());
io.readChunk(bufferMsg.inputBuffer);
return true;
}
return false;
});
tbb::flow::function_node< BufferMsg, BufferMsg > compressor(g, tbb::flow::unlimited, BufferCompressor(blockSizeIn100KB));
tbb::flow::sequencer_node< BufferMsg > ordering(g, [](const BufferMsg& buffer)->size_t {
return buffer.seqId;
});
tbb::flow::function_node< BufferMsg > output_writer(g, tbb::flow::serial, [&io](const BufferMsg& bufferMsg) {
io.writeChunk(bufferMsg.outputBuffer);
BufferMsg::destroyBufferMsg(bufferMsg);
});
make_edge(file_reader, compressor);
make_edge(compressor, ordering);
make_edge(ordering, output_writer);
file_reader.activate();
g.wait_for_all();
}
//-----------------------------------------------------------------------------------------------------------------------
bool endsWith(const std::string& str, const std::string& suffix) {
return str.find(suffix, str.length() - suffix.length()) != std::string::npos;
}
//-----------------------------------------------------------------------------------------------------------------------
int main(int argc, char* argv[]) {
try {
tbb::tick_count mainStartTime = tbb::tick_count::now();
const std::string archiveExtension = ".bz2";
bool verbose = false;
std::string asyncType;
std::string inputFileName;
int blockSizeIn100KB = 1; // block size in 100KB chunks
size_t memoryLimitIn1MB = 1; // memory limit for compression in megabytes granularity
utility::parse_cli_arguments(argc, argv,
utility::cli_argument_pack()
//"-h" option for displaying help is present implicitly
.arg(blockSizeIn100KB, "-b", "\t block size in 100KB chunks, [1 .. 9]")
.arg(verbose, "-v", "verbose mode")
.arg(memoryLimitIn1MB, "-l", "used memory limit for compression algorithm in 1MB (minimum) granularity")
.arg(asyncType, "-a", "name of the used graph async implementation - can be async_node or async_msg")
.positional_arg(inputFileName, "filename", "input file name")
);
if (inputFileName.empty()) {
throw std::invalid_argument("Input file name is not specified. Try 'fgbzip2 -h' for more information.");
}
if (blockSizeIn100KB < 1 || blockSizeIn100KB > 9) {
throw std::invalid_argument("Incorrect block size. Try 'fgbzip2 -h' for more information.");
}
if (memoryLimitIn1MB < 1) {
throw std::invalid_argument("Incorrect memory limit size. Try 'fgbzip2 -h' for more information.");
}
if (verbose) std::cout << "Input file name: " << inputFileName << std::endl;
if (endsWith(inputFileName, archiveExtension)) {
throw std::invalid_argument("Input file already have " + archiveExtension + " extension.");
}
std::ifstream inputStream(inputFileName.c_str(), std::ios::in | std::ios::binary);
if (!inputStream.is_open()) {
throw std::invalid_argument("Cannot open " + inputFileName + " file.");
}
std::string outputFileName(inputFileName + archiveExtension);
std::ofstream outputStream(outputFileName.c_str(), std::ios::out | std::ios::binary | std::ios::trunc);
if (!outputStream.is_open()) {
throw std::invalid_argument("Cannot open " + outputFileName + " file.");
}
// General interface to work with I/O buffers operations
size_t chunkSize = blockSizeIn100KB * 100 * 1024;
IOOperations io(inputStream, outputStream, chunkSize);
if (asyncType.empty()) {
if (verbose) std::cout << "Running flow graph based compression algorithm." << std::endl;
fgCompression(io, blockSizeIn100KB);
} else if (asyncType == "async_node") {
if (verbose) std::cout << "Running flow graph based compression algorithm with async_node based asynchronous IO operations." << std::endl;
fgCompressionAsyncNode(io, blockSizeIn100KB);
} else if (asyncType == "async_msg") {
if (verbose) std::cout << "Running flow graph based compression algorithm with async_msg based asynchronous IO operations. Using limited memory: " << memoryLimitIn1MB << "MB." << std::endl;
fgCompressionAsyncMsg(io, blockSizeIn100KB, memoryLimitIn1MB);
}
inputStream.close();
outputStream.close();
utility::report_elapsed_time((tbb::tick_count::now() - mainStartTime).seconds());
return 0;
} catch (std::exception& e) {
std::cerr << "Error occurred. Error text is : \"" << e.what() << "\"\n";
return -1;
}
}
#else
int main() {
utility::report_skipped();
return 0;
}
#endif /* __TBB_PREVIEW_ASYNC_NODE && __TBB_CPP11_LAMBDAS_PRESENT */

View File

@@ -0,0 +1,253 @@
/*
Copyright (c) 2005-2020 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.
*/
/*-------------------------------------------------------------*/
/*--- Huffman coding low-level stuff ---*/
/*--- huffman.cpp ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
The original source for this example:
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
This program, "bzip2", the associated library "libbzip2", and all
documentation, are copyright (C) 1996-2010 Julian R Seward. All
rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
3. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
4. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Julian Seward, jseward@bzip.org
bzip2/libbzip2 version 1.0.6 of 6 September 2010
------------------------------------------------------------------ */
#include "bzlib_private.h"
/*---------------------------------------------------*/
#define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
#define DEPTHOF(zz1) ((zz1) & 0x000000ff)
#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
#define ADDWEIGHTS(zw1,zw2) \
(WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
(1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
#define UPHEAP(z) \
{ \
Int32 zz, tmp; \
zz = z; tmp = heap[zz]; \
while (weight[tmp] < weight[heap[zz >> 1]]) { \
heap[zz] = heap[zz >> 1]; \
zz >>= 1; \
} \
heap[zz] = tmp; \
}
#define DOWNHEAP(z) \
{ \
Int32 zz, yy, tmp; \
zz = z; tmp = heap[zz]; \
while (True) { \
yy = zz << 1; \
if (yy > nHeap) break; \
if (yy < nHeap && \
weight[heap[yy+1]] < weight[heap[yy]]) \
yy++; \
if (weight[tmp] < weight[heap[yy]]) break; \
heap[zz] = heap[yy]; \
zz = yy; \
} \
heap[zz] = tmp; \
}
/*---------------------------------------------------*/
void BZ2_hbMakeCodeLengths ( UChar *len,
Int32 *freq,
Int32 alphaSize,
Int32 maxLen )
{
/*--
Nodes and heap entries run from 1. Entry 0
for both the heap and nodes is a sentinel.
--*/
Int32 nNodes, nHeap, n1, n2, i, j, k;
Bool tooLong;
Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
for (i = 0; i < alphaSize; i++)
weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
while (True) {
nNodes = alphaSize;
nHeap = 0;
heap[0] = 0;
weight[0] = 0;
parent[0] = -2;
for (i = 1; i <= alphaSize; i++) {
parent[i] = -1;
nHeap++;
heap[nHeap] = i;
UPHEAP(nHeap);
}
AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
while (nHeap > 1) {
n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
nNodes++;
parent[n1] = parent[n2] = nNodes;
weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
parent[nNodes] = -1;
nHeap++;
heap[nHeap] = nNodes;
UPHEAP(nHeap);
}
AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
tooLong = False;
for (i = 1; i <= alphaSize; i++) {
j = 0;
k = i;
while (parent[k] >= 0) { k = parent[k]; j++; }
len[i-1] = j;
if (j > maxLen) tooLong = True;
}
if (! tooLong) break;
/* 17 Oct 04: keep-going condition for the following loop used
to be 'i < alphaSize', which missed the last element,
theoretically leading to the possibility of the compressor
looping. However, this count-scaling step is only needed if
one of the generated Huffman code words is longer than
maxLen, which up to and including version 1.0.2 was 20 bits,
which is extremely unlikely. In version 1.0.3 maxLen was
changed to 17 bits, which has minimal effect on compression
ratio, but does mean this scaling step is used from time to
time, enough to verify that it works.
This means that bzip2-1.0.3 and later will only produce
Huffman codes with a maximum length of 17 bits. However, in
order to preserve backwards compatibility with bitstreams
produced by versions pre-1.0.3, the decompressor must still
handle lengths of up to 20. */
for (i = 1; i <= alphaSize; i++) {
j = weight[i] >> 8;
j = 1 + (j / 2);
weight[i] = j << 8;
}
}
}
/*---------------------------------------------------*/
void BZ2_hbAssignCodes ( Int32 *code,
UChar *length,
Int32 minLen,
Int32 maxLen,
Int32 alphaSize )
{
Int32 n, vec, i;
vec = 0;
for (n = minLen; n <= maxLen; n++) {
for (i = 0; i < alphaSize; i++)
if (length[i] == n) { code[i] = vec; vec++; };
vec <<= 1;
}
}
/*---------------------------------------------------*/
void BZ2_hbCreateDecodeTables ( Int32 *limit,
Int32 *base,
Int32 *perm,
UChar *length,
Int32 minLen,
Int32 maxLen,
Int32 alphaSize )
{
Int32 pp, i, j, vec;
pp = 0;
for (i = minLen; i <= maxLen; i++)
for (j = 0; j < alphaSize; j++)
if (length[j] == i) { perm[pp] = j; pp++; };
for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
vec = 0;
for (i = minLen; i <= maxLen; i++) {
vec += (base[i+1] - base[i]);
limit[i] = vec-1;
vec <<= 1;
}
for (i = minLen + 1; i <= maxLen; i++)
base[i] = ((limit[i-1] + 1) << 1) - base[i];
}
/*-------------------------------------------------------------*/
/*--- end huffman.c ---*/
/*-------------------------------------------------------------*/

View File

@@ -0,0 +1,132 @@
/*
Copyright (c) 2005-2020 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.
*/
/*-------------------------------------------------------------*/
/*--- Table for randomising repetitive blocks ---*/
/*--- randtable.cpp ---*/
/*-------------------------------------------------------------*/
/* ------------------------------------------------------------------
The original source for this example:
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.6 of 6 September 2010
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
This program, "bzip2", the associated library "libbzip2", and all
documentation, are copyright (C) 1996-2010 Julian R Seward. All
rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
3. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
4. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Julian Seward, jseward@bzip.org
bzip2/libbzip2 version 1.0.6 of 6 September 2010
------------------------------------------------------------------ */
#include "bzlib_private.h"
/*---------------------------------------------*/
Int32 BZ2_rNums[512] = {
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
936, 638
};
/*-------------------------------------------------------------*/
/*--- end randtable.c ---*/
/*-------------------------------------------------------------*/

View File

@@ -0,0 +1,466 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks. fgbzip2 sample</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,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
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks.<br>fgbzip2 sample</h1>
</div>
<p>
fgbzip2 is a parallel implementation of bzip2 block-sorting file compressor that uses tbb::flow.
The output of this application is fully compatible with bzip2 v1.0.6 or newer.
<br><br>
<i>
This example includes software developed by Julian R Seward. See
<a href="#copyright">here</a> for copyright information.
</i>
<br>
It exemplifies support for asynchronous capabilities in the flow graph API, in particular async_node and async_msg.
<br><br>
This example uses C++11 lambda expressions. Specifying a compiler option such as -std=c++11 or similar might be necessary in order to build the example.
For more information please refer to the documentation for the compiler you use.
</p>
<div class="changes">
<div class="h3-alike">System Requirements</div>
<input type="checkbox">
<div class="show-hide">
<p>
For the most up to date system requirements, see the <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a>
</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Files</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="fgbzip2.cpp">fgbzip2.cpp</a>
<dd>Flow Graph implementation of bzip2 compressor.
<dt><a href="blocksort.cpp">blocksort.cpp</a>
<dd>Block sorting machinery of libbzip2.
<dt><a href="bzlib.cpp">bzlib.cpp</a>
<dd>libbzip2 top-level functions.
<dt><a href="bzlib.h">bzlib.h</a>
<dd>Public header file for the libbzip2.
<dt><a href="bzlib_private.h">bzlib_private.h</a>
<dd>Private header file for the libbzip2.
<dt><a href="compress.cpp">compress.cpp</a>
<dd>Compression machinery of libbzip2.
<dt><a href="crctable.cpp">crctable.cpp</a>
<dd>libbzip2 table for doing CRCs.
<dt><a href="decompress.cpp">decompress.cpp</a>
<dd>Decompression machinery of libbzip2.
<dt><a href="huffman.cpp">huffman.cpp</a>
<dd>Huffman coding low-level stuff of libbzip2.
<dt><a href="randtable.cpp">randtable.cpp</a>
<dd>libbzip2 table for randomising repetitive blocks.
<dt><a href="Makefile">Makefile</a>
<dd>Makefile for building the example.
</dl>
</div>
</div>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="msvs/">msvs</a>
<dd>Contains Microsoft* Visual Studio* workspace for building and running the example (Windows* systems only).
<dt><a href="xcode/">xcode</a>
<dd>Contains Xcode* IDE workspace for building and running the example (macOS* systems only).
</dl>
<p>For information about the minimum supported version of IDE, see <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a></p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Build instructions</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<p>General build directions can be found <a href="../../index.html">here</a>.</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Usage</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><tt>fgbzip2 <i>-h</i></tt>
<dd>Prints the help for command line options
<dt><tt>fgbzip2 [<i>-b</i>=value] [<i>-v</i>] [<i>-l</i>=value] [<i>-a</i>=value] [<i>filename</i>]</tt>
<dd><i>-b</i> block size in 100 KB chunks, [1 .. 9]<br>
<i>-v</i> print diagnostic output to screen<br>
<i>-l</i> used memory limit for compression algorithm with 1 MB (minimum) granularity<br>
<i>-a</i> name of the used graph async realization - can be async_node or async_msg<br>
<i>filename</i> name of the file to compress<br>
<dt>To run a short version of this example, e.g., for use with Intel&reg; Parallel Inspector:
<dd>Build a <i>debug</i> version of the example
(see the <a href="../../index.html">build instructions</a>).
<br>Run it with a small problem size, e.g., <tt>fgbzip2&nbsp;-b=1&nbsp;-a&nbsp;fgbzip2</tt>.
</dl>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a>
<hr>
<a name="copyright"></a>
<div class="changes">
<div class="h3-alike">Legal Information</div>
<input type="checkbox">
<div class="show-hide">
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
<p>
The "libbzip2" sources for this example is
Copyright (c) 1996-2010 Julian R Seward.
All rights reserved.
</p>
<p>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
<ol>
<li>Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
<li>The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
<li>Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
<li>The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
</ol>
</p>
<p>
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,337 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
A1F593A60B8F042A00073279 /* fgbzip2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A1F593A50B8F042A00073279 /* fgbzip2.cpp */; };
EAA00DB11B443FB000A83D1A /* blocksort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAA00D931B443FB000A83D1A /* blocksort.cpp */; };
EAA00DB31B443FB000A83D1A /* bzlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAA00D961B443FB000A83D1A /* bzlib.cpp */; };
EAA00DB51B443FB000A83D1A /* compress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAA00D991B443FB000A83D1A /* compress.cpp */; };
EAA00DB71B443FB000A83D1A /* crctable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAA00D9B1B443FB000A83D1A /* crctable.cpp */; };
EAA00DB91B443FB000A83D1A /* decompress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAA00D9D1B443FB000A83D1A /* decompress.cpp */; };
EAA00DBB1B443FB000A83D1A /* huffman.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAA00DA11B443FB000A83D1A /* huffman.cpp */; };
EAA00DBE1B443FB000A83D1A /* randtable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAA00DAB1B443FB000A83D1A /* randtable.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
C3C58956218B620500DAC94C /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.intel.compilers.icc.latest;
fileType = sourcecode.cpp;
isEditable = 1;
outputFiles = (
);
script = "# Type a script or drag a script file from your workspace to insert its path.\n";
};
/* End PBXBuildRule section */
/* Begin PBXCopyFilesBuildPhase section */
8DD76F690486A84900D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 12;
dstPath = "";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
8DD76F6C0486A84900D96B5E /* fgbzip2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fgbzip2; sourceTree = BUILT_PRODUCTS_DIR; };
A1F593A50B8F042A00073279 /* fgbzip2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = fgbzip2.cpp; path = ../fgbzip2.cpp; sourceTree = SOURCE_ROOT; };
EAA00D931B443FB000A83D1A /* blocksort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = blocksort.cpp; path = ../blocksort.cpp; sourceTree = "<group>"; };
EAA00D951B443FB000A83D1A /* bzlib_private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = bzlib_private.h; path = ../bzlib_private.h; sourceTree = "<group>"; };
EAA00D961B443FB000A83D1A /* bzlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bzlib.cpp; path = ../bzlib.cpp; sourceTree = "<group>"; };
EAA00D971B443FB000A83D1A /* bzlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = bzlib.h; path = ../bzlib.h; sourceTree = "<group>"; };
EAA00D991B443FB000A83D1A /* compress.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = compress.cpp; path = ../compress.cpp; sourceTree = "<group>"; };
EAA00D9B1B443FB000A83D1A /* crctable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = crctable.cpp; path = ../crctable.cpp; sourceTree = "<group>"; };
EAA00D9D1B443FB000A83D1A /* decompress.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = decompress.cpp; path = ../decompress.cpp; sourceTree = "<group>"; };
EAA00DA11B443FB000A83D1A /* huffman.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = huffman.cpp; path = ../huffman.cpp; sourceTree = "<group>"; };
EAA00DAB1B443FB000A83D1A /* randtable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = randtable.cpp; path = ../randtable.cpp; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8DD76F660486A84900D96B5E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
08FB7794FE84155DC02AAC07 /* fgbzip2 */ = {
isa = PBXGroup;
children = (
08FB7795FE84155DC02AAC07 /* Source */,
1AB674ADFE9D54B511CA2CBB /* Products */,
);
name = fgbzip2;
sourceTree = "<group>";
};
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
EAA00D931B443FB000A83D1A /* blocksort.cpp */,
EAA00D951B443FB000A83D1A /* bzlib_private.h */,
EAA00D961B443FB000A83D1A /* bzlib.cpp */,
EAA00D971B443FB000A83D1A /* bzlib.h */,
EAA00D991B443FB000A83D1A /* compress.cpp */,
EAA00D9B1B443FB000A83D1A /* crctable.cpp */,
EAA00D9D1B443FB000A83D1A /* decompress.cpp */,
EAA00DA11B443FB000A83D1A /* huffman.cpp */,
EAA00DAB1B443FB000A83D1A /* randtable.cpp */,
A1F593A50B8F042A00073279 /* fgbzip2.cpp */,
);
name = Source;
sourceTree = "<group>";
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8DD76F6C0486A84900D96B5E /* fgbzip2 */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8DD76F620486A84900D96B5E /* fgbzip2 */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "fgbzip2" */;
buildPhases = (
8DD76F640486A84900D96B5E /* Sources */,
8DD76F660486A84900D96B5E /* Frameworks */,
8DD76F690486A84900D96B5E /* CopyFiles */,
);
buildRules = (
C3C58956218B620500DAC94C /* PBXBuildRule */,
);
dependencies = (
);
name = fgbzip2;
productInstallPath = "$(HOME)/bin";
productName = fgbzip2;
productReference = 8DD76F6C0486A84900D96B5E /* fgbzip2 */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1000;
};
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "fgbzip2" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,
);
mainGroup = 08FB7794FE84155DC02AAC07 /* fgbzip2 */;
projectDirPath = "";
projectRoot = "";
targets = (
8DD76F620486A84900D96B5E /* fgbzip2 */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
8DD76F640486A84900D96B5E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
EAA00DB91B443FB000A83D1A /* decompress.cpp in Sources */,
EAA00DBB1B443FB000A83D1A /* huffman.cpp in Sources */,
EAA00DB31B443FB000A83D1A /* bzlib.cpp in Sources */,
EAA00DB71B443FB000A83D1A /* crctable.cpp in Sources */,
A1F593A60B8F042A00073279 /* fgbzip2.cpp in Sources */,
EAA00DB11B443FB000A83D1A /* blocksort.cpp in Sources */,
EAA00DBE1B443FB000A83D1A /* randtable.cpp in Sources */,
EAA00DB51B443FB000A83D1A /* compress.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
1DEB923208733DC60010E9CD /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = fgbzip2;
ZERO_LINK = NO;
};
name = Debug64;
};
1DEB923308733DC60010E9CD /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = fgbzip2;
ZERO_LINK = NO;
};
name = Release64;
};
1DEB923608733DC60010E9CD /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++11";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = TBB_PREVIEW_FLOW_GRAPH_NODES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(TBBROOT)/include",
/opt/intel/tbb/include,
);
ICC_CXX_LANG_DIALECT = "c++11";
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
LIBRARY_SEARCH_PATHS = (
"$(TBBROOT)/lib",
/opt/intel/tbb/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = (
"-m64",
"-ltbb_debug",
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Debug64;
};
1DEB923708733DC60010E9CD /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++11";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = TBB_PREVIEW_FLOW_GRAPH_NODES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(TBBROOT)/include",
/opt/intel/tbb/include,
);
ICC_CXX_LANG_DIALECT = "c++11";
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
LIBRARY_SEARCH_PATHS = (
"$(TBBROOT)/lib",
/opt/intel/tbb/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = (
"-m64",
"-ltbb",
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Release64;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "fgbzip2" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB923208733DC60010E9CD /* Debug64 */,
1DEB923308733DC60010E9CD /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "fgbzip2" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB923608733DC60010E9CD /* Debug64 */,
1DEB923708733DC60010E9CD /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View File

@@ -0,0 +1,356 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks (Intel&reg; TBB). Samples on Intel&reg; TBB Flow Graph feature</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,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
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks (Intel&reg; TBB).<br>Samples on Intel&reg; TBB Flow Graph feature</h1>
</div>
<p>
This directory has examples of the Intel TBB Flow Graph feature.
</p>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="dining_philosophers/readme.html">dining_philosophers</a>
<dd>An implementation of dining philosophers in graph using the reserving join node.
<dt><a href="binpack/readme.html">binpack</a>
<dd>A solution to the binpacking problem using a <code>queue_node</code>, a <code>buffer_node</code> and <code>function_nodes</code>.
<dt><a href="logic_sim/readme.html">logic_sim</a>
<dd>A simplistic example of a collection of digital logic gates that can be easily composed into larger circuits.
<dt><a href="som/readme.html">som</a>
<dd>A simple example of a Kohonen Self-Organizing Map using cancellation.
<dt><a href="fgbzip2/readme.html">fgbzip2</a>
<dd>A parallel implementation of bzip2 block-sorting file compressor.
<dt><a href="cholesky/readme.html">cholesky</a>
<dd>Several versions of Cholesky Factorization algorithm implementation.
<dt><a href="stereo/readme.html">stereo</a>
<dd>An implementation of stereo image creation from two images (anaglyph effect).
</dl>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a>
<hr>
<div class="changes">
<div class="h3-alike">Legal Information:</div>
<input type="checkbox">
<div class="show-hide">
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,56 @@
/*
Copyright (c) 2005-2020 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.
*/
#ifndef __TBBexample_graph_logicsim_dlatch_H
#define __TBBexample_graph_logicsim_dlatch_H 1
#include "basics.h"
class D_latch : public composite_node< tuple< signal_t, signal_t >, tuple< signal_t, signal_t > > {
broadcast_node<signal_t> D_port;
broadcast_node<signal_t> E_port;
not_gate a_not;
and_gate<2> first_and;
and_gate<2> second_and;
nor_gate<2> first_nor;
nor_gate<2> second_nor;
graph& my_graph;
typedef composite_node< tuple< signal_t, signal_t >, tuple< signal_t, signal_t > > base_type;
public:
D_latch(graph& g) : base_type(g), my_graph(g), D_port(g), E_port(g), a_not(g), first_and(g), second_and(g),
first_nor(g), second_nor(g)
{
make_edge(D_port, input_port<0>(a_not));
make_edge(D_port, input_port<1>(second_and));
make_edge(E_port, input_port<1>(first_and));
make_edge(E_port, input_port<0>(second_and));
make_edge(a_not, input_port<0>(first_and));
make_edge(first_and, input_port<0>(first_nor));
make_edge(second_and, input_port<1>(second_nor));
make_edge(first_nor, input_port<0>(second_nor));
make_edge(second_nor, input_port<1>(first_nor));
base_type::input_ports_type input_tuple(D_port, E_port);
base_type::output_ports_type output_tuple(output_port<0>(first_nor), output_port<0>(second_nor));
base_type::set_external_ports(input_tuple, output_tuple);
base_type::add_visible_nodes(D_port, E_port, a_not, first_and, second_and, first_nor, second_nor);
}
~D_latch() {}
};
#endif /* __TBBexample_graph_logicsim_dlatch_H */

View File

@@ -0,0 +1,52 @@
# Copyright (c) 2005-2020 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.
# Common Makefile that builds and runs example.
PROG=test_all
ARGS=4
PERF_RUN_ARGS=auto silent
# Try to find icl.exe
CXX1 = $(TBB_CXX)-
CXX2 = $(CXX1:icl.exe-=icl.exe)
CXX = $(CXX2:-=cl.exe)
# The C++ compiler options
MYCXXFLAGS = /TP /EHsc /W3 /nologo /D _CONSOLE /D _MBCS /D WIN32 /D _CRT_SECURE_NO_DEPRECATE $(CXXFLAGS)
MYLDFLAGS =/INCREMENTAL:NO /NOLOGO /DEBUG /FIXED:NO $(LDFLAGS)
all: release test
release: *.cpp
$(CXX) $(PROG).cpp /MD /O2 /D NDEBUG $(MYCXXFLAGS) /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
debug: *.cpp
$(CXX) $(PROG).cpp /MDd /Od /Zi /D TBB_USE_DEBUG /D _DEBUG $(MYCXXFLAGS) /link tbb_debug.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
profile: *.cpp
$(CXX) $(PROG).cpp /MD /O2 /Zi /D NDEBUG $(MYCXXFLAGS) /D TBB_USE_THREADING_TOOLS /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
clean:
@cmd.exe /C del $(PROG).exe *.obj *.?db *.manifest
test:
$(PROG) $(ARGS)
compiler_check:
@$(CXX) >nul 2>&1 || echo "$(CXX) command not found. Check if CXX=$(CXX) is set properly"
perf_build: release
perf_run:
$(PROG) $(PERF_RUN_ARGS)

View File

@@ -0,0 +1,554 @@
/*
Copyright (c) 2005-2020 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.
*/
#ifndef __TBBexample_graph_logicsim_basics_H
#define __TBBexample_graph_logicsim_basics_H 1
#include <cstdio>
#include <string>
#include "tbb/tick_count.h"
#include "tbb/flow_graph.h"
#include "../../common/utility/utility.h"
#ifndef _WIN32
#include <sys/time.h>
#include <unistd.h>
void rt_sleep(int msec) {
usleep(msec*1000);
}
#else //_WIN32
#undef OLDUNIXTIME
#undef STDTIME
#include <windows.h>
void rt_sleep(int msec) {
Sleep(msec);
}
#endif /* _WIN32 */
using namespace std;
using namespace tbb;
using namespace tbb::flow;
typedef enum { low=0, high, undefined } signal_t;
template<int N> class gate;
template<>
class gate<1> : public composite_node< tuple< signal_t >, tuple< signal_t > > {
protected:
typedef indexer_node<signal_t> input_port_t;
typedef multifunction_node< input_port_t::output_type, tuple<signal_t> > gate_fn_t;
typedef gate_fn_t::output_ports_type ports_type;
typedef composite_node< tuple< signal_t >, tuple< signal_t > > base_type;
public:
template <typename Body>
gate(graph& g, Body b) : base_type(g), my_graph(g), in_ports(g), gate_fn(g, 1, b) {
make_edge(in_ports, gate_fn);
base_type::input_ports_type input_tuple(input_port<0>(in_ports));
base_type::output_ports_type output_tuple(output_port<0>(gate_fn));
base_type::set_external_ports(input_tuple, output_tuple);
base_type::add_visible_nodes(in_ports, gate_fn);
}
virtual ~gate() {}
gate& operator=(const gate& src) { return *this; }
protected:
graph& my_graph;
private:
input_port_t in_ports;
gate_fn_t gate_fn;
};
template<>
class gate<2> : public composite_node< tuple< signal_t, signal_t >, tuple< signal_t > > {
protected:
typedef indexer_node<signal_t,signal_t> input_port_t;
typedef multifunction_node< input_port_t::output_type, tuple<signal_t> > gate_fn_t;
typedef gate_fn_t::output_ports_type ports_type;
typedef composite_node< tuple< signal_t, signal_t >, tuple< signal_t > > base_type;
public:
template <typename Body>
gate(graph& g, Body b) : base_type(g), my_graph(g), in_ports(g), gate_fn(g, 1, b) {
make_edge(in_ports, gate_fn);
base_type::input_ports_type input_tuple(input_port<0>(in_ports),input_port<1>(in_ports));
base_type::output_ports_type output_tuple(output_port<0>(gate_fn));
base_type::set_external_ports(input_tuple, output_tuple);
base_type::add_visible_nodes(in_ports, gate_fn);
}
virtual ~gate() {}
gate& operator=(const gate& src) { return *this; }
protected:
graph& my_graph;
private:
input_port_t in_ports;
gate_fn_t gate_fn;
};
template<>
class gate<3> : public composite_node< tuple< signal_t, signal_t, signal_t >, tuple< signal_t > > {
protected:
typedef indexer_node<signal_t, signal_t, signal_t> input_port_t;
typedef multifunction_node< input_port_t::output_type, tuple<signal_t> > gate_fn_t;
typedef gate_fn_t::output_ports_type ports_type;
typedef composite_node< tuple< signal_t, signal_t, signal_t >, tuple< signal_t > > base_type;
public:
template <typename Body>
gate(graph& g, Body b) : base_type(g), my_graph(g), in_ports(g), gate_fn(g, 1, b) {
make_edge(in_ports, gate_fn);
base_type::input_ports_type input_tuple(input_port<0>(in_ports),input_port<1>(in_ports),input_port<2>(in_ports));
base_type::output_ports_type output_tuple(output_port<0>(gate_fn));
base_type::set_external_ports(input_tuple, output_tuple);
base_type::add_visible_nodes(in_ports, gate_fn);
}
virtual ~gate() {}
gate& operator=(const gate& src) { return *this; }
protected:
graph& my_graph;
private:
input_port_t in_ports;
gate_fn_t gate_fn;
};
template<>
class gate<4> : public composite_node< tuple< signal_t, signal_t, signal_t, signal_t >, tuple< signal_t > > {
protected:
typedef indexer_node<signal_t, signal_t, signal_t, signal_t> input_port_t;
typedef multifunction_node< input_port_t::output_type, tuple<signal_t> > gate_fn_t;
typedef gate_fn_t::output_ports_type ports_type;
typedef composite_node< tuple< signal_t, signal_t, signal_t, signal_t >, tuple< signal_t > > base_type;
public:
template <typename Body>
gate(graph& g, Body b) : base_type(g), my_graph(g), in_ports(g), gate_fn(g, 1, b) {
make_edge(in_ports, gate_fn);
base_type::input_ports_type input_tuple(input_port<0>(in_ports),input_port<1>(in_ports),input_port<2>(in_ports), input_port<3>(in_ports));
base_type::output_ports_type output_tuple(output_port<0>(gate_fn));
base_type::set_external_ports(input_tuple, output_tuple);
base_type::add_visible_nodes(in_ports, gate_fn);
}
virtual ~gate() {}
gate& operator=(const gate& src) { return *this; }
protected:
graph& my_graph;
private:
input_port_t in_ports;
gate_fn_t gate_fn;
};
// Input devices
class steady_signal {
graph& my_graph;
signal_t init_signal;
write_once_node<signal_t> signal_node;
public:
steady_signal(graph& g, signal_t v) :
my_graph(g), init_signal(v), signal_node(g) {}
steady_signal(const steady_signal& src) :
my_graph(src.my_graph), init_signal(src.init_signal),
signal_node(src.my_graph) {}
~steady_signal() {}
// Assignment is ignored
steady_signal& operator=(const steady_signal& src) { return *this; }
write_once_node<signal_t>& get_out() { return signal_node; }
void activate() { signal_node.try_put(init_signal); }
};
class pulse {
class clock_body {
size_t& ms;
int& reps;
signal_t val;
public:
clock_body(size_t& _ms, int& _reps) : ms(_ms), reps(_reps), val(low) {}
bool operator()(signal_t& out) {
rt_sleep((int)ms);
if (reps>0) --reps;
if (val==low) val = high;
else val = low;
out = val;
return reps>0 || reps == -1;
}
};
graph& my_graph;
size_t ms, init_ms;
int reps, init_reps;
input_node<signal_t> clock_node;
public:
pulse(graph& g, size_t _ms=1000, int _reps=-1) :
my_graph(g), ms(_ms), init_ms(_ms), reps(_reps), init_reps(_reps),
clock_node(g, clock_body(ms, reps))
{}
pulse(const pulse& src) :
my_graph(src.my_graph), ms(src.init_ms), init_ms(src.init_ms),
reps(src.init_reps), init_reps(src.init_reps),
clock_node(src.my_graph, clock_body(ms, reps))
{}
~pulse() {}
// Assignment changes the behavior of LHS to that of the RHS, but doesn't change owning graph
pulse& operator=(const pulse& src) {
ms = src.ms; init_ms = src.init_ms; reps = src.reps; init_reps = src.init_reps;
return *this;
}
input_node<signal_t>& get_out() { return clock_node; }
void activate() { clock_node.activate(); }
void reset() { reps = init_reps; }
};
class push_button {
graph& my_graph;
overwrite_node<signal_t> push_button_node;
public:
push_button(graph& g) : my_graph(g), push_button_node(g) {
push_button_node.try_put(low);
}
push_button(const push_button& src) :
my_graph(src.my_graph), push_button_node(src.my_graph) {
push_button_node.try_put(low);
}
~push_button() {}
// Assignment is ignored
push_button& operator=(const push_button& src) { return *this; }
overwrite_node<signal_t>& get_out() { return push_button_node; }
void press() { push_button_node.try_put(high); }
void release() { push_button_node.try_put(low); }
};
class toggle {
graph& my_graph;
signal_t state;
overwrite_node<signal_t> toggle_node;
public:
toggle(graph& g) : my_graph(g), state(undefined), toggle_node(g) {}
toggle(const toggle& src) : my_graph(src.my_graph), state(undefined),
toggle_node(src.my_graph) {}
~toggle() {}
// Assignment ignored
toggle& operator=(const toggle& src) { return *this; }
overwrite_node<signal_t>& get_out() { return toggle_node; }
void flip() {
if (state==high) state = low;
else state = high;
toggle_node.try_put(state);
}
void activate() {
state = low;
toggle_node.try_put(state);
}
};
// Basic gates
class buffer : public gate<1> {
using gate<1>::my_graph;
typedef gate<1>::ports_type ports_type;
class buffer_body {
signal_t state;
bool touched;
public:
buffer_body() : state(undefined), touched(false) {}
void operator()(const input_port_t::output_type &v, ports_type& p) {
if (!touched || state != cast_to<signal_t>(v)) {
state = cast_to<signal_t>(v);
tbb::flow::get<0>(p).try_put(state);
touched = true;
}
}
};
public:
buffer(graph& g) : gate<1>(g, buffer_body()) {}
buffer(const buffer& src) : gate<1>(src.my_graph, buffer_body()) {}
~buffer() {}
};
class not_gate : public gate<1> {
using gate<1>::my_graph;
typedef gate<1>::ports_type ports_type;
class not_body {
signal_t port;
bool touched;
public:
not_body() : port(undefined), touched(false) {}
void operator()(const input_port_t::output_type &v, ports_type& p) {
if (!touched || port != cast_to<signal_t>(v)) {
port = cast_to<signal_t>(v);
signal_t state = low;
if (port==low) state = high;
tbb::flow::get<0>(p).try_put(state);
touched = true;
}
}
};
public:
not_gate(graph& g) : gate<1>(g, not_body()) {}
not_gate(const not_gate& src) : gate<1>(src.my_graph, not_body()) {}
~not_gate() {}
};
template <int N>
class and_gate : public gate<N> {
using gate<N>::my_graph;
typedef typename gate<N>::ports_type ports_type;
typedef typename gate<N>::input_port_t::output_type from_input;
class and_body {
signal_t *ports;
signal_t state;
bool touched;
public:
and_body() : state(undefined), touched(false) {
ports = new signal_t[N];
for (int i=0; i<N; ++i) ports[i] = undefined;
}
void operator()(const from_input& v, ports_type& p) {
ports[v.tag()] = cast_to<signal_t>(v);
signal_t new_state=high;
size_t i=0;
while (i<N) {
if (ports[i] == low) { new_state = low; break; }
else if (ports[i] == undefined && new_state != low) { new_state = undefined; }
++i;
}
if (!touched || state != new_state) {
state = new_state;
tbb::flow::get<0>(p).try_put(state);
touched = true;
}
}
};
public:
and_gate(graph& g) : gate<N>(g, and_body()) {}
and_gate(const and_gate<N>& src) : gate<N>(src.my_graph, and_body()) {}
~and_gate() {}
};
template<int N>
class or_gate : public gate<N> {
using gate<N>::my_graph;
typedef typename gate<N>::ports_type ports_type;
typedef typename gate<N>::input_port_t::output_type from_input;
class or_body {
signal_t *ports;
signal_t state;
bool touched;
public:
or_body() : state(undefined), touched(false) {
ports = new signal_t[N];
for (int i=0; i<N; ++i) ports[i] = undefined;
}
void operator()(const from_input& v, ports_type& p) {
ports[v.tag()] = cast_to<signal_t>(v);
signal_t new_state=low;
size_t i=0;
while (i<N) {
if (ports[i] == high) { new_state = high; break; }
else if (ports[i] == undefined && new_state != high) { new_state = undefined; }
++i;
}
if (!touched || state != new_state) {
state = new_state;
tbb::flow::get<0>(p).try_put(state);
touched = true;
}
}
};
public:
or_gate(graph& g) : gate<N>(g, or_body()) {}
or_gate(const or_gate& src) : gate<N>(src.my_graph, or_body()) {}
~or_gate() {}
};
template <int N>
class xor_gate : public gate<N> {
using gate<N>::my_graph;
typedef typename gate<N>::ports_type ports_type;
typedef typename gate<N>::input_port_t input_port_t;
class xor_body {
signal_t *ports;
signal_t state;
bool touched;
public:
xor_body() : state(undefined), touched(false) {
ports = new signal_t[N];
for (int i=0; i<N; ++i) ports[i] = undefined;
}
void operator()(const typename input_port_t::output_type &v, ports_type& p) {
ports[v.tag()] = cast_to<signal_t>(v);
signal_t new_state=low;
size_t i=0, highs=0;
while (i<N) {
if (ports[i] == undefined) { new_state = undefined; }
else if (ports[i] == high && new_state == low) { new_state = high; ++highs; }
else if (ports[i] == high && highs > 0) { new_state = low; break; }
else if (ports[i] == high ) { ++highs; }
++i;
}
if (!touched || state != new_state) {
state = new_state;
tbb::flow::get<0>(p).try_put(state);
touched = true;
}
}
};
public:
xor_gate(graph& g) : gate<N>(g, xor_body()) {}
xor_gate(const xor_gate& src) : gate<N>(src.my_graph, xor_body()) {}
~xor_gate() {}
};
template <int N>
class nor_gate : public gate<N> {
using gate<N>::my_graph;
typedef typename gate<N>::ports_type ports_type;
typedef typename gate<N>::input_port_t input_port_t;
class nor_body {
signal_t *ports;
signal_t state;
bool touched;
public:
nor_body() : state(undefined), touched(false) {
ports = new signal_t[N];
for (int i=0; i<N; ++i) ports[i] = undefined;
}
void operator()(const typename input_port_t::output_type &v, ports_type& p) {
ports[v.tag()] = cast_to<signal_t>(v);
signal_t new_state=low;
size_t i=0;
while (i<N) {
if (ports[i] == high) { new_state = high; break; }
else if (ports[i] == undefined && new_state != high) { new_state = undefined; }
++i;
}
if (new_state == high) new_state = low;
else if (new_state == low) new_state = high;
if (!touched || state != new_state) {
state = new_state;
tbb::flow::get<0>(p).try_put(state);
touched = true;
}
}
};
public:
nor_gate(graph& g) : gate<N>(g, nor_body()) {}
nor_gate(const nor_gate& src) : gate<N>(src.my_graph, nor_body()) {}
~nor_gate() {}
};
// Output devices
class led {
class led_body {
signal_t &state;
string &label;
bool report_changes;
bool touched;
public:
led_body(signal_t &s, string &l, bool r) :
state(s), label(l), report_changes(r), touched(false)
{}
continue_msg operator()(signal_t b) {
if (!touched || b!=state) {
state = b;
if (state != undefined && report_changes) {
if (state) printf("%s: (*)\n", label.c_str());
else printf("%s: ( )\n", label.c_str());
}
touched = false;
}
return continue_msg();
}
};
graph& my_graph;
string label;
signal_t state;
bool report_changes;
function_node<signal_t, continue_msg> led_node;
public:
led(graph& g, string l, bool rc=false) : my_graph(g), label(l), state(undefined),
report_changes(rc),
led_node(g, 1, led_body(state, label, report_changes))
{}
led(const led& src) : my_graph(src.my_graph), label(src.label), state(undefined),
report_changes(src.report_changes),
led_node(src.my_graph, 1, led_body(state, label, report_changes))
{}
~led() {}
// Assignment changes the behavior of LHS to that of the RHS, but doesn't change owning graph
// state is set to undefined so that next signal changes it
led& operator=(const led& src) {
label = src.label; state = undefined; report_changes = src.report_changes;
return *this;
}
function_node<signal_t, continue_msg>& get_in() { return led_node; }
void display() {
if (state == high) printf("%s: (*)\n", label.c_str());
else if (state == low) printf("%s: ( )\n", label.c_str());
else printf("%s: (u)\n", label.c_str());
}
signal_t get_value() { return state; }
};
class digit : public gate<4> {
using gate<4>::my_graph;
typedef gate<4>::ports_type ports_type;
typedef gate<4>::input_port_t input_port_t;
class digit_body {
signal_t ports[4];
static const int N = 4;
unsigned int &state;
string &label;
bool& report_changes;
public:
digit_body(unsigned int &s, string &l, bool& r) : state(s), label(l), report_changes(r) {
for (int i=0; i<N; ++i) ports[i] = undefined;
}
void operator()(const input_port_t::output_type& v, ports_type& p) {
unsigned int new_state = 0;
ports[v.tag()] = cast_to<signal_t>(v);
if (ports[0] == high) ++new_state;
if (ports[1] == high) new_state += 2;
if (ports[2] == high) new_state += 4;
if (ports[3] == high) new_state += 8;
if (state != new_state) {
state = new_state;
if (report_changes) {
printf("%s: %x\n", label.c_str(), state);
}
}
}
};
string label;
unsigned int state;
bool report_changes;
public:
digit(graph& g, string l, bool rc=false) :
gate<4>(g, digit_body(state, label, report_changes)),
label(l), state(0), report_changes(rc) {}
digit(const digit& src) :
gate<4>(src.my_graph, digit_body(state, label, report_changes)),
label(src.label), state(0), report_changes(src.report_changes) {}
~digit() {}
// Assignment changes the behavior of LHS to that of the RHS, but doesn't change owning graph.
// state is reset as in constructors
digit& operator=(const digit& src) {
label = src.label; state = 0; report_changes = src.report_changes;
return *this;
}
void display() { printf("%s: %x\n", label.c_str(), state); }
unsigned int get_value() { return state; }
};
#endif /* __TBBexample_graph_logicsim_basics_H */

View File

@@ -0,0 +1,58 @@
/*
Copyright (c) 2005-2020 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.
*/
#ifndef __TBBexample_graph_logicsim_fba_H
#define __TBBexample_graph_logicsim_fba_H 1
#include "one_bit_adder.h"
typedef composite_node< tuple< signal_t, signal_t, signal_t, signal_t, signal_t, signal_t, signal_t, signal_t, signal_t >,
tuple< signal_t, signal_t, signal_t, signal_t, signal_t > > fba_base_type;
class four_bit_adder : public fba_base_type {
graph& my_graph;
std::vector<one_bit_adder> four_adders;
public:
four_bit_adder(graph& g) : fba_base_type(g), my_graph(g), four_adders(4, one_bit_adder(g)) {
make_connections();
set_up_composite();
}
four_bit_adder(const four_bit_adder& src) :
fba_base_type(src.my_graph), my_graph(src.my_graph), four_adders(4, one_bit_adder(src.my_graph))
{
make_connections();
set_up_composite();
}
~four_bit_adder() {}
private:
void make_connections() {
make_edge(output_port<1>(four_adders[0]), input_port<0>(four_adders[1]));
make_edge(output_port<1>(four_adders[1]), input_port<0>(four_adders[2]));
make_edge(output_port<1>(four_adders[2]), input_port<0>(four_adders[3]));
}
void set_up_composite() {
fba_base_type::input_ports_type input_tuple(input_port<0>(four_adders[0]/*CI*/), input_port<1>(four_adders[0]), input_port<2>(four_adders[0]), input_port<1>(four_adders[1]), input_port<2>(four_adders[1]), input_port<1>(four_adders[2]), input_port<2>(four_adders[2]), input_port<1>(four_adders[3]), input_port<2>(four_adders[3]));
fba_base_type::output_ports_type output_tuple(output_port<0>(four_adders[0]), output_port<0>(four_adders[1]), output_port<0>(four_adders[2]), output_port<0>(four_adders[3]),output_port<1>(four_adders[3]/*CO*/));
fba_base_type::set_external_ports(input_tuple, output_tuple);
}
};
#endif /* __TBBexample_graph_logicsim_fba_H */

View File

@@ -0,0 +1,99 @@
/*
Copyright (c) 2005-2020 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.
*/
#ifndef __TBBexample_graph_logicsim_oba_H
#define __TBBexample_graph_logicsim_oba_H 1
namespace P {
//input ports
const int CI = 0;
const int A0 = 1;
const int B0 = 2;
const int A1 = 3;
const int B1 = 4;
const int A2 = 5;
const int B2 = 6;
const int A3 = 7;
const int B3 = 8;
//output_ports
const int S0 = 0;
const int S1 = 1;
const int S2 = 2;
const int S3 = 3;
#if USE_TWO_BIT_FULL_ADDER
const int CO = 2;
#else
const int CO = 4;
#endif
}
#include "basics.h"
class one_bit_adder : public composite_node< tuple< signal_t, signal_t, signal_t >, tuple< signal_t, signal_t > > {
broadcast_node<signal_t> A_port;
broadcast_node<signal_t> B_port;
broadcast_node<signal_t> CI_port;
xor_gate<2> FirstXOR;
xor_gate<2> SecondXOR;
and_gate<2> FirstAND;
and_gate<2> SecondAND;
or_gate<2> FirstOR;
graph& my_graph;
typedef composite_node< tuple< signal_t, signal_t, signal_t >, tuple< signal_t, signal_t > > base_type;
public:
one_bit_adder(graph& g) : base_type(g), my_graph(g), A_port(g), B_port(g), CI_port(g), FirstXOR(g),
SecondXOR(g), FirstAND(g), SecondAND(g), FirstOR(g) {
make_connections();
set_up_composite();
}
one_bit_adder(const one_bit_adder& src) :
base_type(src.my_graph), my_graph(src.my_graph), A_port(src.my_graph), B_port(src.my_graph),
CI_port(src.my_graph), FirstXOR(src.my_graph), SecondXOR(src.my_graph),
FirstAND(src.my_graph), SecondAND(src.my_graph), FirstOR(src.my_graph)
{
make_connections();
set_up_composite();
}
~one_bit_adder() {}
private:
void make_connections() {
make_edge(A_port, input_port<0>(FirstXOR));
make_edge(A_port, input_port<0>(FirstAND));
make_edge(B_port, input_port<1>(FirstXOR));
make_edge(B_port, input_port<1>(FirstAND));
make_edge(CI_port, input_port<1>(SecondXOR));
make_edge(CI_port, input_port<1>(SecondAND));
make_edge(FirstXOR, input_port<0>(SecondXOR));
make_edge(FirstXOR, input_port<0>(SecondAND));
make_edge(SecondAND, input_port<0>(FirstOR));
make_edge(FirstAND, input_port<1>(FirstOR));
}
void set_up_composite() {
base_type::input_ports_type input_tuple(CI_port, A_port, B_port);
base_type::output_ports_type output_tuple(output_port<0>(SecondXOR), output_port<0>(FirstOR));
base_type::set_external_ports( input_tuple, output_tuple);
base_type::add_visible_nodes(A_port, B_port, CI_port, FirstXOR, SecondXOR, FirstAND, SecondAND, FirstOR );
}
};
#endif /* __TBBexample_graph_logicsim_oba_H */

View File

@@ -0,0 +1,406 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks. logic_sim sample</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,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
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks.<br>Logic_sim sample</h1>
</div>
<p>
This directory contains a simple tbb::flow example that performs
simplistic digital logic simulations with basic logic gates that can
be easily composed to create more interesting circuits. It
exemplifies the multifunction_node and the indexer_node CPF, among others. </p>
<div class="changes">
<div class="h3-alike">System Requirements</div>
<input type="checkbox">
<div class="show-hide">
<p>
For the most up to date system requirements, see the <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a>
</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Files</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="basics.h">basics.h</a>
<dd>Several I/O devices and basic gates.
<dt><a href="one_bit_adder.h">one_bit_adder.h</a>
<dd>A one-bit full adder composed of basic gates.
<dt><a href="four_bit_adder.h">four_bit_adder.h</a>
<dd>A four-bit full adder composed of one-bit adders.
<dt><a href="D_latch.h">D_latch.h</a>
<dd>A D-latch composed of basic gates.
<dt><a href="test_all.cpp">test_all.cpp</a>
<dd>A simple test program that exercises the code in the headers.
<dt><a href="Makefile">Makefile</a>
<dd>Makefile for building the example.
</dl>
</div>
</div>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="msvs/">msvs</a>
<dd>Contains Microsoft* Visual Studio* workspace for building and running the example with the Intel&reg; C++ Compiler (Windows* systems only).
</dl>
<p>For information about the minimum supported version of IDE, see <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a></p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Build instructions</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<p>General build directions can be found <a href="../../index.html">here</a>.</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Usage</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><tt>test_all <i>-h</i></tt>
<dd>Prints the help for command line options
<dt><tt>test_all [<i>#threads</i>=value] [<i>verbose</i>] [<i>silent</i>] [<i>#threads</i>]</tt>
<dd><tt><i>#threads</i></tt> is the number of threads to use; a range of the form <tt><i>low[:high]</i></tt> where <tt><i>low</i></tt> and optional <tt><i>high</i></tt> are non-negative integers, or <tt><i>'auto'</i></tt> for a platform-specific default number.<br>
<tt><i>verbose</i></tt> print diagnostic output to screen<br>
<tt><i>silent</i></tt> limits output to timing info; overrides verbose<br>
<dt>To run a short version of this example, e.g., for use with Intel&reg; Parallel Inspector:
<dd>Build a <i>debug</i> version of the example
(see the <a href="../../index.html">build instructions</a>).
<br>Run it with the desired number of threads, e.g., <tt>test_all&nbsp;4</tt>.
</dl>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a>
<hr>
<div class="changes">
<div class="h3-alike">Legal Information</div>
<input type="checkbox">
<div class="show-hide">
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,637 @@
/*
Copyright (c) 2005-2020 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 "tbb/tbb_config.h"
#include "tbb/global_control.h"
#include <cstdio>
#include "../../common/utility/utility.h"
#include "../../common/utility/get_default_num_threads.h"
#if __TBB_FLOW_GRAPH_CPP11_FEATURES
#if _MSC_VER
#pragma warning (disable: 4503) // Suppress "decorated name length exceeded, name was truncated" warning
#endif
#define USE_TWO_BIT_FULL_ADDER 1
#include "basics.h"
#include "one_bit_adder.h"
#if USE_TWO_BIT_FULL_ADDER
#include "two_bit_adder.h"
#else
#include "four_bit_adder.h"
#endif
#include "D_latch.h"
#include <cassert>
// User-specified globals with default values
bool verbose = false; // prints bin details and other diagnostics to screen
bool silent = false; // suppress all output except for time
#endif // __TBB_FLOW_GRAPH_CPP11_FEATURES
int main(int argc, char *argv[]) {
#if __TBB_FLOW_GRAPH_CPP11_FEATURES
try {
utility::thread_number_range threads(utility::get_default_num_threads);
utility::parse_cli_arguments(argc, argv,
utility::cli_argument_pack()
//"-h" option for displaying help is present implicitly
.positional_arg(threads,"#threads",utility::thread_number_range_desc)
.arg(verbose,"verbose"," print diagnostic output to screen")
.arg(silent,"silent"," limits output to timing info; overrides verbose")
);
if (silent) verbose = false; // make silent override verbose
tick_count start = tick_count::now();
for(int p = threads.first; p <= threads.last; p = threads.step(p)) {
tbb::global_control c(tbb::global_control::max_allowed_parallelism, p);
if (!silent) cout << "graph test running on " << p << " threads.\n";
graph g;
{ // test buffer: 0, 1
buffer b(g);
toggle input(g);
led output(g, "OUTPUT", false); // false means we will explicitly call display to see LED
make_edge(input.get_out(), input_port<0>(b));
make_edge(output_port<0>(b), output.get_in());
if (!silent) printf("Testing buffer...\n");
input.activate(); // 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
input.flip(); // 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
}
{ // test not_gate: 0, 1
not_gate n(g);
toggle input(g);
led output(g, "OUTPUT", false);
make_edge(input.get_out(), input_port<0>(n));
make_edge(output_port<0>(n), output.get_in());
if (!silent) printf("Testing not_gate...\n");
input.activate(); // 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input.flip(); // 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
}
{ // test two-input and_gate: 00, 01, 10, 11
and_gate<2> a(g);
toggle input0(g);
toggle input1(g);
led output(g, "OUTPUT", false);
make_edge(input0.get_out(), input_port<0>(a));
make_edge(input1.get_out(), input_port<1>(a));
make_edge(output_port<0>(a), output.get_in());
if (!silent) printf("Testing and_gate...\n");
input1.activate(); input0.activate(); // 0 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
input0.flip(); // 0 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
input1.flip(); input0.flip(); // 1 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
input0.flip(); // 1 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
}
{ // test three-input or_gate: 000, 001, 010, 100, 011, 101, 110, 111
or_gate<3> o(g);
toggle input0(g);
toggle input1(g);
toggle input2(g);
led output(g, "OUTPUT", false);
make_edge(input0.get_out(), input_port<0>(o));
make_edge(input1.get_out(), input_port<1>(o));
make_edge(input2.get_out(), input_port<2>(o));
make_edge(output_port<0>(o), output.get_in());
if (!silent) printf("Testing or_gate...\n");
input2.activate(); input1.activate(); input0.activate(); // 0 0 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
input0.flip(); // 0 0 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input1.flip(); input0.flip(); // 0 1 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input2.flip(); input1.flip(); // 1 0 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input2.flip(); input1.flip(); input0.flip(); // 0 1 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input2.flip(); input1.flip(); // 1 0 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input1.flip(); input0.flip(); // 1 1 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input0.flip(); // 1 1 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
}
{ // test two-input xor_gate: 00, 01, 10, 11
xor_gate<2> x(g);
toggle input0(g);
toggle input1(g);
led output(g, "OUTPUT", false);
make_edge(input0.get_out(), input_port<0>(x));
make_edge(input1.get_out(), input_port<1>(x));
make_edge(output_port<0>(x), output.get_in());
if (!silent) printf("Testing xor_gate...\n");
input1.activate(); input0.activate(); // 0 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
input0.flip(); // 0 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input1.flip(); input0.flip(); // 1 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input0.flip(); // 1 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
}
{ // test two-input nor_gate: 00, 01, 10, 11
nor_gate<2> n(g);
toggle input0(g);
toggle input1(g);
led output(g, "OUTPUT", false);
make_edge(input0.get_out(), input_port<0>(n));
make_edge(input1.get_out(), input_port<1>(n));
make_edge(output_port<0>(n), output.get_in());
if (!silent) printf("Testing nor_gate...\n");
input1.activate(); input0.activate(); // 0 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == high);
input0.flip(); // 0 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
input1.flip(); input0.flip(); // 1 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
input0.flip(); // 1 1
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == low);
}
{ // test steady_signal and digit
steady_signal input0(g, high);
steady_signal input1(g, low);
and_gate<2> a(g);
or_gate<2> o(g);
xor_gate<2> x(g);
nor_gate<2> n(g);
digit output(g, "OUTPUT", false);
make_edge(input0.get_out(), input_port<0>(a));
make_edge(input1.get_out(), input_port<1>(a));
make_edge(output_port<0>(a), input_port<0>(output));
make_edge(input0.get_out(), input_port<0>(o));
make_edge(input1.get_out(), input_port<1>(o));
make_edge(output_port<0>(o), input_port<1>(output));
make_edge(input0.get_out(), input_port<0>(x));
make_edge(input1.get_out(), input_port<1>(x));
make_edge(output_port<0>(x), input_port<2>(output));
make_edge(input0.get_out(), input_port<0>(n));
make_edge(input1.get_out(), input_port<1>(n));
make_edge(output_port<0>(n), input_port<3>(output));
if (!silent) printf("Testing steady_signal...\n");
input0.activate(); // 1
input1.activate(); // 0
g.wait_for_all();
if (!silent) output.display();
assert(output.get_value() == 6);
}
{ // test push_button
push_button p(g);
buffer b(g);
led output(g, "OUTPUT", !silent); // true means print all LED state changes
make_edge(p.get_out(), input_port<0>(b));
make_edge(output_port<0>(b), output.get_in());
if (!silent) printf("Testing push_button...\n");
p.press();
p.release();
p.press();
p.release();
g.wait_for_all();
}
{ // test one_bit_adder
one_bit_adder my_adder(g);
toggle A(g);
toggle B(g);
toggle CarryIN(g);
led Sum(g, "SUM");
led CarryOUT(g, "CarryOUT");
make_edge(A.get_out(), input_port<P::A0>(my_adder));
make_edge(B.get_out(), input_port<P::B0>(my_adder));
make_edge(CarryIN.get_out(), input_port<P::CI>(my_adder));
make_edge(output_port<P::S0>(my_adder), Sum.get_in());
make_edge(output_port<1>(my_adder), CarryOUT.get_in());
A.activate();
B.activate();
CarryIN.activate();
if (!silent) printf("A on\n");
A.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == high) && (CarryOUT.get_value() == low));
if (!silent) printf("A off\n");
A.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
if (!silent) printf("B on\n");
B.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == high) && (CarryOUT.get_value() == low));
if (!silent) printf("B off\n");
B.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
if (!silent) printf("CarryIN on\n");
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == high) && (CarryOUT.get_value() == low));
if (!silent) printf("CarryIN off\n");
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
if (!silent) printf("A&B on\n");
A.flip();
B.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == high));
if (!silent) printf("A&B off\n");
A.flip();
B.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
if (!silent) printf("A&CarryIN on\n");
A.flip();
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == high));
if (!silent) printf("A&CarryIN off\n");
A.flip();
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
if (!silent) printf("B&CarryIN on\n");
B.flip();
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == high));
if (!silent) printf("B&CarryIN off\n");
B.flip();
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
if (!silent) printf("A&B&CarryIN on\n");
A.flip();
B.flip();
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == high) && (CarryOUT.get_value() == high));
if (!silent) printf("A&B&CarryIN off\n");
A.flip();
B.flip();
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == low) && (CarryOUT.get_value() == low));
}
#if USE_TWO_BIT_FULL_ADDER
{ // test two_bit_adder
if (!silent) printf("testing two_bit adder\n");
two_bit_adder two_adder(g);
std::vector<toggle> A(2, toggle(g));
std::vector<toggle> B(2, toggle(g));
toggle CarryIN(g);
digit Sum(g, "SUM");
led CarryOUT(g, "CarryOUT");
make_edge(A[0].get_out(), input_port<P::A0>(two_adder));
make_edge(B[0].get_out(), input_port<P::B0>(two_adder));
make_edge(output_port<P::S0>(two_adder), input_port<0>(Sum));
make_edge(A[1].get_out(), input_port<P::A1>(two_adder));
make_edge(B[1].get_out(), input_port<P::B1>(two_adder));
make_edge(output_port<P::S1>(two_adder), input_port<1>(Sum));
make_edge(CarryIN.get_out(), input_port<P::CI>(two_adder));
make_edge(output_port<P::CO>(two_adder), CarryOUT.get_in());
// Activate all switches at low state
for (int i=0; i<2; ++i) {
A[i].activate();
B[i].activate();
}
CarryIN.activate();
if (!silent) printf("1+0\n");
A[0].flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 1) && (CarryOUT.get_value() == low));
if (!silent) printf("0+1\n");
A[0].flip();
B[0].flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 1) && (CarryOUT.get_value() == low));
}
#else
{ // test four_bit_adder
four_bit_adder four_adder(g);
std::vector<toggle> A(4, toggle(g));
std::vector<toggle> B(4, toggle(g));
toggle CarryIN(g);
digit Sum(g, "SUM");
led CarryOUT(g, "CarryOUT");
make_edge(A[0].get_out(), input_port<P::A0>(four_adder));
make_edge(B[0].get_out(), input_port<P::B0>(four_adder));
make_edge(output_port<P::S0>(four_adder), input_port<0>(Sum));
make_edge(A[1].get_out(), input_port<P::A1>(four_adder));
make_edge(B[1].get_out(), input_port<P::B1>(four_adder));
make_edge(output_port<P::S1>(four_adder), input_port<1>(Sum));
make_edge(A[2].get_out(), input_port<P::A2>(four_adder));
make_edge(B[2].get_out(), input_port<P::B2>(four_adder));
make_edge(output_port<P::S2>(four_adder), input_port<2>(Sum));
make_edge(A[3].get_out(), input_port<P::A3>(four_adder));
make_edge(B[3].get_out(), input_port<P::B3>(four_adder));
make_edge(output_port<P::S3>(four_adder), input_port<3>(Sum));
make_edge(CarryIN.get_out(), input_port<P::CI>(four_adder));
make_edge(output_port<P::CO>(four_adder), CarryOUT.get_in());
// Activate all switches at low state
for (int i=0; i<4; ++i) {
A[i].activate();
B[i].activate();
}
CarryIN.activate();
if (!silent) printf("1+0\n");
A[0].flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 1) && (CarryOUT.get_value() == low));
if (!silent) printf("0+1\n");
A[0].flip();
B[0].flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 1) && (CarryOUT.get_value() == low));
if (!silent) printf("3+4\n");
A[0].flip();
A[1].flip();
B[0].flip();
B[2].flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 7) && (CarryOUT.get_value() == low));
if (!silent) printf("6+1\n");
A[0].flip();
A[2].flip();
B[0].flip();
B[2].flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 7) && (CarryOUT.get_value() == low));
if (!silent) printf("0+0+carry\n");
A[1].flip();
A[2].flip();
B[0].flip();
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 1) && (CarryOUT.get_value() == low));
if (!silent) printf("15+15+carry\n");
A[0].flip();
A[1].flip();
A[2].flip();
A[3].flip();
B[0].flip();
B[1].flip();
B[2].flip();
B[3].flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 0xf) && (CarryOUT.get_value() == high));
if (!silent) printf("8+8\n");
A[0].flip();
A[1].flip();
A[2].flip();
B[0].flip();
B[1].flip();
B[2].flip();
CarryIN.flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 0) && (CarryOUT.get_value() == high));
if (!silent) printf("0+0\n");
A[3].flip();
B[3].flip();
g.wait_for_all();
if (!silent) Sum.display();
if (!silent) CarryOUT.display();
assert((Sum.get_value() == 0) && (CarryOUT.get_value() == low));
}
#endif
{ // test D_latch
D_latch my_d_latch(g);
toggle D(g);
pulse E(g, 500, 4); // clock changes every 500ms; stops after 4 changes
led Q(g, " Q", verbose); // if true, LEDs print at every state change
led notQ(g, "~Q", verbose);
make_edge(D.get_out(), input_port<0>(my_d_latch));
make_edge(E.get_out(), input_port<1>(my_d_latch));
make_edge(output_port<0>(my_d_latch), Q.get_in());
make_edge(output_port<1>(my_d_latch), notQ.get_in());
D.activate();
if (!silent) printf("Toggling D\n");
E.activate();
D.flip();
g.wait_for_all();
if (!silent && !verbose) { Q.display(); notQ.display(); }
assert((Q.get_value() == high) && (notQ.get_value() == low));
E.reset();
if (!silent) printf("Toggling D\n");
E.activate();
D.flip();
g.wait_for_all();
if (!silent && !verbose) { Q.display(); notQ.display(); }
assert((Q.get_value() == low) && (notQ.get_value() == high));
E.reset();
if (!silent) printf("Toggling D\n");
E.activate();
D.flip();
g.wait_for_all();
if (!silent && !verbose) { Q.display(); notQ.display(); }
assert((Q.get_value() == high) && (notQ.get_value() == low));
E.reset();
if (!silent) printf("Toggling D\n");
E.activate();
D.flip();
g.wait_for_all();
if (!silent && !verbose) { Q.display(); notQ.display(); }
assert((Q.get_value() == low) && (notQ.get_value() == high));
E.reset();
if (!silent) printf("Toggling D\n");
E.activate();
D.flip();
g.wait_for_all();
if (!silent && !verbose) { Q.display(); notQ.display(); }
assert((Q.get_value() == high) && (notQ.get_value() == low));
}
}
utility::report_elapsed_time((tbb::tick_count::now() - start).seconds());
return 0;
} catch(std::exception& e) {
cerr<<"error occurred. error text is :\"" <<e.what()<<"\"\n";
return 1;
}
#else
utility::report_skipped();
return 0;
#endif // __TBB_FLOW_GRAPH_CPP11_FEATURES
}

View File

@@ -0,0 +1,55 @@
/*
Copyright (c) 2005-2020 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.
*/
#ifndef __TBBexample_graph_logicsim_tba_H
#define __TBBexample_graph_logicsim_tba_H 1
#include "one_bit_adder.h"
class two_bit_adder : public composite_node< tuple< signal_t, signal_t, signal_t, signal_t, signal_t >,
tuple< signal_t, signal_t, signal_t > > {
graph& my_graph;
std::vector<one_bit_adder> two_adders;
typedef composite_node< tuple< signal_t, signal_t, signal_t, signal_t, signal_t >,
tuple< signal_t, signal_t, signal_t > > base_type;
public:
two_bit_adder(graph& g) : base_type(g), my_graph(g), two_adders(2, one_bit_adder(g)) {
make_connections();
set_up_composite();
}
two_bit_adder(const two_bit_adder& src) :
base_type(src.my_graph), my_graph(src.my_graph), two_adders(2, one_bit_adder(src.my_graph))
{
make_connections();
set_up_composite();
}
~two_bit_adder() {}
private:
void make_connections() {
make_edge(output_port<1>(two_adders[0]), input_port<0>(two_adders[1]));
}
void set_up_composite() {
base_type::input_ports_type input_tuple(input_port<0>(two_adders[0]/*CI*/), input_port<1>(two_adders[0]), input_port<2>(two_adders[0]), input_port<1>(two_adders[1]), input_port<2>(two_adders[1]));
base_type::output_ports_type output_tuple(output_port<0>(two_adders[0]), output_port<0>(two_adders[1]),output_port<1>(two_adders[1]/*CO*/));
base_type::set_external_ports(input_tuple, output_tuple);
}
};
#endif /* __TBBexample_graph_logicsim_tba_H */

View File

@@ -0,0 +1,44 @@
# Copyright (c) 2005-2020 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.
# Common Makefile that builds and runs example.
# Just specify your program basename
PROG=som
ARGS=
LIGHT_ARGS=4
# Trying to find if icl.exe is set
CXX1 = $(TBB_CXX)-
CXX2 = $(CXX1:icl.exe-=icl.exe)
CXX = $(CXX2:-=cl.exe)
# The C++ compiler options
MYCXXFLAGS = /TP /EHsc /W3 /nologo /D _CONSOLE /D _MBCS /D WIN32 /D _CRT_SECURE_NO_DEPRECATE $(CXXFLAGS)
MYLDFLAGS =/INCREMENTAL:NO /NOLOGO /DEBUG /FIXED:NO $(LDFLAGS)
all: release test
release:
$(CXX) ./som_graph.cpp ./som.cpp /MD /O2 /D NDEBUG $(MYCXXFLAGS) /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
debug:
$(CXX) ./som_graph.cpp ./som.cpp /MDd /Od /Zi /D _DEBUG $(MYCXXFLAGS) /link tbb_debug.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
profile:
$(CXX) ./som_graph.cpp ./som.cpp /MD /O2 /Zi /D NDEBUG $(MYCXXFLAGS) /D TBB_USE_THREADING_TOOLS /link tbb.lib $(LIBS) $(MYLDFLAGS) /OUT:$(PROG).exe
clean:
@cmd.exe /C del $(PROG).exe *.obj *.?db *.manifest
test:
$(PROG) $(ARGS)
light_test:
$(PROG) $(LIGHT_ARGS)

View File

@@ -0,0 +1,391 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks. Self-Organizing Map (SOM) sample</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,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
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks.<br>Self-Organizing Map (SOM) sample</h1>
</div>
<p>
The Self-Organizing Map demonstrates tbb::flow and the use of cancellation in scheduling multiple iterations of
map updates.
<br><br>
For tutorials on Self-organizing Maps, see <a href="http://www.ai-junkie.com/ann/som/som1.html">here</a> and
<a href="http://davis.wpi.edu/~matt/courses/soms/">here</a>.
<br><br>
The program trains the map with several examples, splitting the map into subsections and looking for best-match
for multiple examples. When an example is used to update the map, the graphs examining the sections being
updated for the next example are cancelled and restarted after the update.
</p>
<div class="changes">
<div class="h3-alike">System Requirements</div>
<input type="checkbox">
<div class="show-hide">
<p>
For the most up to date system requirements, see the <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a>
</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Files</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="som_graph.cpp">som_graph.cpp</a>
<dd>The main program.
<dt><a href="som.cpp">som.cpp</a>
<dd>Utilities for handling the map.
<dt><a href="som.h">som.h</a>
<dd>Definitions and utilities.
<dt><a href="Makefile">Makefile</a>
<dd>Makefile for building the example.
</dl>
</div>
</div>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="msvs/">msvs</a>
<dd>Contains Microsoft* Visual Studio* workspace for building and running the example (Windows* systems only).
<dt><a href="xcode/">xcode</a>
<dd>Contains Xcode* IDE workspace for building and running the example (macOS* systems only).
</dl>
<p>For information about the minimum supported version of IDE, see <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a></p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Build instructions</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<p>General build directions can be found <a href="../../index.html">here</a>.</p>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a>
<hr>
<div class="changes">
<div class="h3-alike">Legal Information</div>
<input type="checkbox">
<div class="show-hide">
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,213 @@
/*
Copyright (c) 2005-2020 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.
*/
//
// Self-organizing map in TBB flow::graph
//
// we will do a color map (the simple example.)
//
// serial algorithm
//
// initialize map with vectors (could be random, gradient, or something else)
// for some number of iterations
// update radius r, weight of change L
// for each example V
// find the best matching unit
// for each part of map within radius of BMU W
// update vector: W(t+1) = W(t) + w(dist)*L*(V - W(t))
#include "som.h"
#include "tbb/task.h"
std::ostream& operator<<( std::ostream &out, const SOM_element &s) {
out << "(";
for(int i=0;i<(int)s.w.size();++i) {
out << s.w[i];
if(i < (int)s.w.size()-1) {
out << ",";
}
}
out << ")";
return out;
}
void remark_SOM_element(const SOM_element &s) {
printf("(");
for(int i=0;i<(int)s.w.size();++i) {
printf("%g",s.w[i]);
if(i < (int)s.w.size()-1) {
printf(",");
}
}
printf(")");
}
std::ostream& operator<<( std::ostream &out, const search_result_type &s) {
out << "<";
out << get<RADIUS>(s);
out << ", " << get<XV>(s);
out << ", ";
out << get<YV>(s);
out << ">";
return out;
}
void remark_search_result_type(const search_result_type &s) {
printf("<%g,%d,%d>", get<RADIUS>(s), get<XV>(s), get<YV>(s));
}
double
randval( double lowlimit, double highlimit) {
return double(rand()) / double(RAND_MAX) * (highlimit - lowlimit) + lowlimit;
}
void
find_data_ranges(teaching_vector_type &teaching, SOM_element &max_range, SOM_element &min_range ) {
if(teaching.size() == 0) return;
max_range = min_range = teaching[0];
for(int i = 1; i < (int)teaching.size(); ++i) {
max_range.elementwise_max(teaching[i]);
min_range.elementwise_min(teaching[i]);
}
}
void add_fraction_of_difference( SOM_element &to, SOM_element const &from, double frac) {
for(int i = 0; i < (int)from.size(); ++i) {
to[i] += frac*(from[i] - to[i]);
}
}
double
distance_squared(SOM_element x, SOM_element y) {
double rval = 0.0; for(int i=0;i<(int)x.size();++i) {
double diff = x[i] - y[i];
rval += diff*diff;
}
return rval;
}
void SOMap::initialize(InitializeType it, SOM_element &max_range, SOM_element &min_range) {
for(int x = 0; x < xMax; ++x) {
for(int y = 0; y < yMax; ++y) {
for( int i = 0; i < (int)max_range.size(); ++i) {
if(it == InitializeRandom) {
my_map[x][y][i] = (randval(min_range[i], max_range[i]));
}
else if(it == InitializeGradient) {
my_map[x][y][i] = ((double)(x+y)/(xMax+yMax)*(max_range[i]-min_range[i]) + min_range[i]);
}
}
}
}
}
// subsquare [low,high)
double
SOMap::BMU_range( const SOM_element &s, int &xval, int &yval, subsquare_type &r) {
double min_distance_squared = DBL_MAX;
task &my_task = task::self();
int min_x = -1;
int min_y = -1;
for(int x = r.rows().begin(); x != r.rows().end(); ++x) {
for( int y = r.cols().begin(); y != r.cols().end(); ++y) {
double dist = distance_squared(s,my_map[x][y]);
if(dist < min_distance_squared) {
min_distance_squared = dist;
min_x = x;
min_y = y;
}
if(cancel_test && my_task.is_cancelled()) {
xval = r.rows().begin();
yval = r.cols().begin();
return DBL_MAX;
}
}
}
xval = min_x;
yval = min_y;
return sqrt(min_distance_squared);
}
void
SOMap::epoch_update_range( SOM_element const &s, int epoch, int min_x, int min_y, double radius, double learning_rate, blocked_range<int> &r) {
int min_xiter = (int)((double)min_x - radius);
if(min_xiter < 0) min_xiter = 0;
int max_xiter = (int)((double)min_x + radius);
if(max_xiter > (int)my_map.size()-1) max_xiter = (int)my_map.size()-1;
for(int xx = r.begin(); xx <= r.end(); ++xx) {
double xrsq = (xx-min_x)*(xx-min_x);
double ysq = radius*radius - xrsq; // max extent of y influence
double yd;
if(ysq > 0) {
yd = sqrt(ysq);
int lb = (int)(min_y - yd);
int ub = (int)(min_y + yd);
for(int yy = lb; yy < ub; ++yy) {
if(yy >= 0 && yy < (int)my_map[xx].size()) {
// [xx, yy] is in the range of the update.
double my_rsq = xrsq + (yy-min_y)*(yy-min_y); // distance from BMU squared
double theta = exp(-(radius*radius) /(2.0* my_rsq));
add_fraction_of_difference(my_map[xx][yy], s, theta * learning_rate);
}
}
}
}
}
void SOMap::teach(teaching_vector_type &in) {
for(int i = 0; i < nPasses; ++i ) {
int j = (int)(randval(0, (double)in.size())); // this won't be reproducible.
if(j == in.size()) --j;
int min_x = -1;
int min_y = -1;
subsquare_type br2(0, (int)my_map.size(), 1, 0, (int)my_map[0].size(), 1);
(void) BMU_range(in[j],min_x, min_y, br2); // just need min_x, min_y
// radius of interest
double radius = max_radius * exp(-(double)i*radius_decay_rate);
// update circle is min_xiter to max_xiter inclusive.
double learning_rate = max_learning_rate * exp( -(double)i * learning_decay_rate);
epoch_update(in[j], i, min_x, min_y, radius, learning_rate);
}
}
void SOMap::debug_output() {
printf("SOMap:\n");
for(int i = 0; i < (int)(this->my_map.size()); ++i) {
for(int j = 0; j < (int)(this->my_map[i].size()); ++j) {
printf( "map[%d, %d] == ", i, j );
remark_SOM_element( this->my_map[i][j] );
printf("\n");
}
}
}
#define RED 0
#define GREEN 1
#define BLUE 2
void readInputData() {
my_teaching.push_back(SOM_element());
my_teaching.push_back(SOM_element());
my_teaching.push_back(SOM_element());
my_teaching.push_back(SOM_element());
my_teaching.push_back(SOM_element());
my_teaching[0][RED] = 1.0; my_teaching[0][GREEN] = 0.0; my_teaching[0][BLUE] = 0.0;
my_teaching[1][RED] = 0.0; my_teaching[1][GREEN] = 1.0; my_teaching[1][BLUE] = 0.0;
my_teaching[2][RED] = 0.0; my_teaching[2][GREEN] = 0.0; my_teaching[2][BLUE] = 1.0;
my_teaching[3][RED] = 0.3; my_teaching[3][GREEN] = 0.3; my_teaching[3][BLUE] = 0.0;
my_teaching[4][RED] = 0.5; my_teaching[4][GREEN] = 0.5; my_teaching[4][BLUE] = 0.9;
}

View File

@@ -0,0 +1,157 @@
/*
Copyright (c) 2005-2020 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.
*/
//
// Self-organizing map
//
// support for self-ordering maps
#ifndef __SOM_H__
#define __SOM_H__
#include <vector>
#include <cstdlib>
#include <cmath>
#include <cfloat>
#include <iostream>
#include <cstdio>
#include "tbb/flow_graph.h"
#include "tbb/blocked_range2d.h"
using namespace tbb;
using namespace tbb::flow;
typedef blocked_range2d<int> subsquare_type;
typedef tuple<double,int,int> search_result_type;
std::ostream& operator<<( std::ostream &out, const search_result_type &s);
#define RADIUS 0 // for the std::gets
#define XV 1
#define YV 2
// to have single definitions of static variables, define _MAIN_C_ in the main program
//
#ifdef _MAIN_C_
#define DEFINE // nothing
#define INIT(n) = n
#else // not in main file
#define DEFINE extern
#define INIT(n) // nothing
#endif // _MAIN_C_
DEFINE int nElements INIT(3); // length of input vectors, matching vector in map
DEFINE double max_learning_rate INIT(0.8); // decays exponentially
DEFINE double radius_decay_rate;
DEFINE double learning_decay_rate INIT(0.005);
DEFINE double max_radius;
DEFINE bool extra_debug INIT(false);
DEFINE bool cancel_test INIT(false);
DEFINE int xMax INIT(100);
DEFINE int yMax INIT(100);
DEFINE int nPasses INIT(100);
enum InitializeType { InitializeRandom, InitializeGradient };
#define RED 0
#define GREEN 1
#define BLUE 2
class SOM_element;
void remark_SOM_element(const SOM_element &s);
// all SOM_element vectors are the same length (nElements), so we do not have
// to range-check the vector accesses.
class SOM_element {
std::vector<double> w;
public:
friend std::ostream& operator<<( std::ostream &out, const SOM_element &s);
friend void remark_SOM_element(const SOM_element &s);
SOM_element() : w(nElements,0.0) {}
double &operator[](int indx) { return w.at(indx); }
const double &operator[](int indx) const { return w.at(indx); }
bool operator==(SOM_element const &other) const {
for(size_t i=0;i<size();++i) {
if(w[i] != other.w[i]) {
return false;
}
}
return true;
}
bool operator!=(SOM_element const &other) const { return !operator==(other); }
void elementwise_max(SOM_element const &other) {
for(size_t i = 0; i < w.size(); ++i) if(w[i] < other.w[i]) w[i] = other.w[i];
}
void elementwise_min(SOM_element const &other) {
for(size_t i = 0; i < w.size(); ++i) if(w[i] > other.w[i]) w[i] = other.w[i];
}
size_t size() const { return w.size(); }
};
typedef std::vector<SOM_element> teaching_vector_type;
DEFINE SOM_element max_range;
DEFINE SOM_element min_range;
extern double randval( double lowlimit, double highlimit);
extern void find_data_ranges(teaching_vector_type &teaching, SOM_element &max_range, SOM_element &min_range );
extern void add_fraction_of_difference( SOM_element &to, SOM_element &from, double frac);
DEFINE teaching_vector_type my_teaching;
class SOMap {
std::vector< std::vector< SOM_element > > my_map;
public:
SOMap(int xSize, int ySize) {
my_map.reserve(xSize);
for(int i = 0; i < xSize; ++i) {
my_map.push_back(teaching_vector_type());
my_map[i].reserve(ySize);
for(int j = 0; j < ySize;++j) {
my_map[i].push_back(SOM_element());
}
}
}
size_t size() { return my_map.size(); }
void initialize(InitializeType it, SOM_element &max_range, SOM_element &min_range);
teaching_vector_type &operator[](int indx) { return my_map[indx]; }
SOM_element &at(int xVal, int yVal) { return my_map[xVal][yVal]; }
SOM_element &at(search_result_type const &s) { return my_map[flow::get<1>(s)][flow::get<2>(s)]; }
void epoch_update( SOM_element const &s, int epoch, int min_x, int min_y, double radius, double learning_rate) {
int min_xiter = (int)((double)min_x - radius);
if(min_xiter < 0) min_xiter = 0;
int max_xiter = (int)((double)min_x + radius);
if(max_xiter > (int)my_map.size()-1) max_xiter = (int)(my_map.size()-1);
blocked_range<int> br1(min_xiter, max_xiter, 1);
epoch_update_range(s, epoch, min_x, min_y, radius, learning_rate, br1);
}
void epoch_update_range( SOM_element const &s, int epoch, int min_x, int min_y, double radius, double learning_rate, blocked_range<int> &r);
void teach( teaching_vector_type &id);
void debug_output();
// find BMU given an input, returns distance
double BMU_range(const SOM_element &s, int &xval, int &yval, subsquare_type &r);
double BMU(const SOM_element &s, int &xval, int &yval) {
subsquare_type br(0,(int)my_map.size(),1,0,(int)my_map[0].size(),1);
return BMU_range(s, xval, yval, br);
}
};
extern double distance_squared(SOM_element x, SOM_element y);
void remark_SOM_element(const SOM_element &s);
extern void readInputData();
#endif // __SOM_H__

View File

@@ -0,0 +1,429 @@
/*
Copyright (c) 2005-2020 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.
*/
//
// Self-organizing map in TBB flow::graph
//
// This is an example of the use of cancellation in a graph. After a point in searching for
// the best match for an example, two examples are looked for simultaneously. When the
// earlier example is found and the update radius is determined, the affected searches
// for the subsequent example are cancelled, and after the update they are restarted.
// As the update radius shrinks fewer searches are cancelled, and by the last iterations
// virtually all the work done for the speculating example is useful.
//
// first, a simple implementation with only one example vector
// at a time.
//
// we will do a color map (the simple example.)
//
// graph algorithm
//
// for some number of iterations
// update radius r, weight of change L
// for each example V
// use graph to find BMU
// for each part of map within radius of BMU W
// update vector: W(t+1) = W(t) + w(dist)*L*(V - W(t))
#define _MAIN_C_ 1
#include "som.h"
#include "tbb/flow_graph.h"
#include "tbb/blocked_range2d.h"
#include "tbb/tick_count.h"
#include "tbb/task_arena.h"
#include "../../common/utility/utility.h"
#include "../../common/utility/get_default_num_threads.h"
#define RED 0
#define GREEN 1
#define BLUE 2
static int xranges = 1;
static int yranges = 1;
static int xsize = -1;
static int ysize = -1;
static int global_i = 0;
static int speculation_start;
std::vector<int> function_node_execs;
static int xRangeMax = 3;
static int yRangeMax = 3;
static bool dont_speculate = false;
static search_result_type last_update;
class BMU_search_body {
SOMap &my_map;
subsquare_type my_square;
int &fn_tally;
public:
BMU_search_body(SOMap &_m, subsquare_type &_sq, int &fnt) : my_map(_m), my_square(_sq), fn_tally(fnt) { }
BMU_search_body( const BMU_search_body &other) : my_map(other.my_map), my_square(other.my_square), fn_tally(other.fn_tally) { }
search_result_type operator()(const SOM_element s) {
int my_x;
int my_y;
double min_dist = my_map.BMU_range(s, my_x, my_y, my_square);
++fn_tally; // count how many times this function_node executed
return search_result_type(min_dist, my_x, my_y);
}
};
typedef function_node<SOM_element, search_result_type> search_node;
typedef broadcast_node<SOM_element> b_node;
typedef std::vector< search_node *> search_node_vector_type;
typedef std::vector< search_node_vector_type > search_node_array_type;
typedef std::vector< graph *> graph_vector_type;
typedef std::vector< graph_vector_type > graph_array_type;
#define SPECULATION_CNT 2
graph *g[SPECULATION_CNT]; // main graph; there should only be one per epoch
b_node *send_to[SPECULATION_CNT]; // broadcast node to send exemplar to all function_nodes
queue_node<search_result_type> *q[SPECULATION_CNT]; // queue for function nodes to put their results in
// each function_node should have its own graph
search_node_array_type* s_array[SPECULATION_CNT]; // 2d array of function nodes
graph_array_type* g_array[SPECULATION_CNT]; // 2d array of graphs
// All graphs must locate in the same arena.
graph* construct_graph(task_arena& ta) {
graph* result;
ta.execute([&result]{result = new graph;});
return result;
}
// build a set of SPECULATION_CNT graphs, each of which consists of a broadcast_node,
// xranges x yranges function_nodes, and one queue_node for output.
// once speculation starts, if i % SPECULATION_CNT is the current graph, (i+1) % SPECULATION_CNT
// is the first speculation, and so on.
void
build_BMU_graph(SOMap &map1, task_arena& ta) {
// build current graph
xsize = ((int)map1.size() + xranges - 1) / xranges;
ysize = ((int)map1[0].size() + yranges - 1) / yranges;
function_node_execs.clear();
function_node_execs.reserve(xranges*yranges+1);
for(int ii = 0; ii < xranges*yranges+1;++ii) function_node_execs.push_back(0);
for(int scnt = 0; scnt < SPECULATION_CNT; ++scnt) {
g[scnt] = construct_graph(ta);
send_to[scnt] = new b_node(*(g[scnt])); // broadcast node to the function_nodes
q[scnt] = new queue_node<search_result_type>(*(g[scnt])); // output queue
// create the function_nodes, tie to the graph
s_array[scnt] = new search_node_array_type;
s_array[scnt]->reserve(xranges);
g_array[scnt] = new graph_array_type;
g_array[scnt]->reserve(xranges);
for(int i = 0; i < (int)map1.size(); i += xsize) {
int xindex = i / xsize;
s_array[scnt]->push_back(search_node_vector_type());
(*s_array[scnt])[xindex].reserve(yranges);
g_array[scnt]->push_back(graph_vector_type());
(*g_array[scnt])[xindex].reserve(yranges);
for( int j = 0; j < (int)map1[0].size(); j += ysize) {
int offset = (i/xsize)*yranges + (j / ysize);
int xmax = (i + xsize) > (int)map1.size() ? (int)map1.size() : i + xsize;
int ymax = (j + ysize) > (int)map1[0].size() ? (int)map1[0].size() : j + ysize;
subsquare_type sst(i,xmax,1,j,ymax,1);
BMU_search_body bb(map1,sst,function_node_execs[offset]);
graph *g_local = construct_graph(ta);
search_node *s = new search_node(*g_local, serial, bb); // copies Body
(*g_array[scnt])[xindex].push_back(g_local);
(*s_array[scnt])[xindex].push_back(s);
make_edge(*(send_to[scnt]), *s); // broadcast_node -> function_node
make_edge(*s, *(q[scnt])); // function_node -> queue_node
}
}
}
}
// Wait for the 2D array of flow::graphs.
void wait_for_all_graphs(int cIndex) { // cIndex ranges over [0 .. SPECULATION_CNT - 1]
for(int x = 0; x < xranges; ++x) {
for(int y = 0; y < yranges; ++y) {
(*g_array[cIndex])[x][y]->wait_for_all();
}
}
}
void
destroy_BMU_graph() {
for(int scnt = 0; scnt < SPECULATION_CNT; ++scnt) {
for( int i = 0; i < (int)(*s_array[scnt]).size(); ++i ) {
for(int j = 0; j < (int)(*s_array[scnt])[i].size(); ++j) {
delete (*s_array[scnt])[i][j];
delete (*g_array[scnt])[i][j];
}
}
(*s_array[scnt]).clear();
delete s_array[scnt];
(*g_array[scnt]).clear();
delete g_array[scnt];
delete q[scnt];
delete send_to[scnt];
delete g[scnt];
}
}
void find_subrange_overlap(int const &xval, int const &yval, double const &radius, int &xlow, int &xhigh, int &ylow, int &yhigh) {
xlow = int((xval-radius)/xsize);
xhigh = int((xval+radius)/xsize);
ylow = int((yval-radius)/ysize);
yhigh = int((yval+radius)/ysize);
// circle may fall partly outside map
if(xlow < 0) xlow = 0;
if(xhigh >= xranges) xhigh = xranges - 1;
if(ylow < 0) ylow = 0;
if(yhigh >= yranges) yhigh = yranges - 1;
}
bool overlap( int &xval, int &yval, search_result_type &sr) {
int xlow, xhigh, ylow, yhigh;
find_subrange_overlap(get<XV>(sr), get<YV>(sr), get<RADIUS>(sr), xlow, xhigh, ylow, yhigh);
return xval >= xlow && xval <= xhigh && yval >= ylow && yval <= yhigh;
}
void
cancel_submaps(int &xval, int &yval, double &radius, int indx) {
int xlow;
int xhigh;
int ylow;
int yhigh;
find_subrange_overlap(xval, yval, radius, xlow, xhigh, ylow, yhigh);
for(int x = xlow; x <= xhigh; ++x) {
for(int y = ylow; y <= yhigh; ++y) {
(*g_array[indx])[x][y]->root_task()->cancel_group_execution();
}
}
}
void
restart_submaps(int &xval, int &yval, double &radius, int indx, SOM_element &vector) {
int xlow;
int xhigh;
int ylow;
int yhigh;
find_subrange_overlap(xval, yval, radius, xlow, xhigh, ylow, yhigh);
for(int x = xlow; x <= xhigh; ++x) {
for(int y = ylow; y <= yhigh; ++y) {
// have to reset the graph
(*g_array[indx])[x][y]->root_task()->context()->reset();
// and re-submit the exemplar for search.
(*s_array[indx])[x][y]->try_put(vector);
}
}
}
search_result_type
graph_BMU( int indx ) { // indx ranges over [0 .. SPECULATION_CNT -1]
wait_for_all_graphs(indx); // wait for the array of subgraphs
(g[indx])->wait_for_all();
std::vector<search_result_type> all_srs(xRangeMax*yRangeMax,search_result_type(DBL_MAX,-1,-1));
search_result_type sr;
search_result_type min_sr;
get<RADIUS>(min_sr) = DBL_MAX;
int result_count = 0;
while((q[indx])->try_get(sr)) {
++result_count;
// figure which submap this came from
int x = get<XV>(sr) / xsize;
int y = get<YV>(sr) / ysize;
int offset = x*yranges+y; // linearized subscript
all_srs[offset] = sr;
if(get<RADIUS>(sr) < get<RADIUS>(min_sr))
min_sr = sr;
else if(get<RADIUS>(sr) == get<RADIUS>(min_sr)) {
if(get<XV>(sr) < get<XV>(min_sr)) {
min_sr = sr;
}
else if((get<XV>(sr) == get<XV>(min_sr) &&
get<YV>(sr) < get<YV>(min_sr)))
{
min_sr = sr;
}
}
}
return min_sr;
// end of one epoch
}
void graph_teach(SOMap &map1, teaching_vector_type &in, task_arena& ta) {
build_BMU_graph(map1, ta);
// normally the training would pick random exemplars to teach the SOM. We need
// the process to be reproducible, so we will pick the exemplars in order, [0, in.size())
int next_j = 0;
for(int epoch = 0; epoch < nPasses; ++epoch) {
global_i = epoch;
bool canceled_submaps = false;
int j = next_j; // try to make reproducible
next_j = (epoch+1) % in.size();
search_result_type min_sr;
if(epoch < speculation_start) {
(send_to[epoch%SPECULATION_CNT])->try_put(in[j]);
}
else if(epoch == speculation_start) {
(send_to[epoch%SPECULATION_CNT])->try_put(in[j]);
if(epoch < nPasses-1) {
(send_to[(epoch+1)%SPECULATION_CNT])->try_put(in[next_j]);
}
}
else if(epoch < nPasses - 1) {
(send_to[(epoch+1)%SPECULATION_CNT])->try_put(in[next_j]);
}
min_sr = graph_BMU(epoch % SPECULATION_CNT); //calls wait_for_all()
double min_distance = get<0>(min_sr);
double radius = max_radius * exp(-(double)epoch*radius_decay_rate);
double learning_rate = max_learning_rate * exp(-(double)epoch * learning_decay_rate);
if(epoch >= speculation_start && epoch < (nPasses - 1)) {
// have to cancel the affected submaps
cancel_submaps(get<XV>(min_sr), get<YV>(min_sr), radius, (epoch+1)%SPECULATION_CNT);
canceled_submaps = true;
}
map1.epoch_update(in[j], epoch, get<1>(min_sr), get<2>(min_sr), radius, learning_rate);
++global_i;
if(canceled_submaps) {
// do I have to wait for all the non-canceled speculative graph to complete first?
// yes, in case a canceled task was already executing.
wait_for_all_graphs((epoch+1) % SPECULATION_CNT); // wait for the array of subgraphs
restart_submaps(get<1>(min_sr), get<2>(min_sr), radius, (epoch+1)%SPECULATION_CNT, in[next_j]);
}
last_update = min_sr;
get<RADIUS>(last_update) = radius; // not smallest value, but range of effect
}
destroy_BMU_graph();
}
static const double serial_time_adjust = 1.25;
static double radius_fraction = 3.0;
int
main(int argc, char** argv) {
int l_speculation_start;
utility::thread_number_range threads(
utility::get_default_num_threads,
utility::get_default_num_threads() // run only the default number of threads if none specified
);
utility::parse_cli_arguments(argc,argv,
utility::cli_argument_pack()
//"-h" option for for displaying help is present implicitly
.positional_arg(threads,"n-of-threads","number of threads to use; a range of the form low[:high], where low and optional high are non-negative integers or 'auto' for the TBB default.")
// .positional_arg(InputFileName,"input-file","input file name")
// .positional_arg(OutputFileName,"output-file","output file name")
.positional_arg(radius_fraction, "radius-fraction","size of radius at which to start speculating")
.positional_arg(nPasses, "number-of-epochs","number of examples used in learning phase")
.arg(cancel_test, "cancel-test", "test for cancel signal while finding BMU")
.arg(extra_debug, "debug", "additional output")
.arg(dont_speculate,"nospeculate","don't speculate in SOM map teaching")
);
readInputData();
max_radius = (xMax < yMax) ? yMax / 2 : xMax / 2;
// need this value for the 1x1 timing below
radius_decay_rate = -(log(1.0/(double)max_radius) / (double)nPasses);
find_data_ranges(my_teaching, max_range, min_range );
if(extra_debug) {
printf( "Data range: ");
remark_SOM_element(min_range);
printf( " to ");
remark_SOM_element(max_range);
printf( "\n");
}
// find how much time is taken for the single function_node case.
// adjust nPasses so the 1x1 time is somewhere around serial_time_adjust seconds.
// make sure the example test runs for at least 0.5 second.
for(;;) {
// Restrict max concurrency level via task_arena interface
task_arena ta(1);
SOMap map1(xMax,yMax);
speculation_start = nPasses + 1; // Don't speculate
xranges = 1;
yranges = 1;
map1.initialize(InitializeGradient, max_range, min_range);
tick_count t0 = tick_count::now();
graph_teach(map1, my_teaching, ta);
tick_count t1 = tick_count::now();
double nSeconds = (t1-t0).seconds();
if(nSeconds < 0.5) {
xMax *= 2;
yMax *= 2;
continue;
}
double size_adjust = sqrt(serial_time_adjust / nSeconds);
xMax = (int)((double)xMax * size_adjust);
yMax = (int)((double)yMax * size_adjust);
max_radius = (xMax < yMax) ? yMax / 2 : xMax / 2;
radius_decay_rate = log((double)max_radius) / (double)nPasses;
if(extra_debug) {
printf("original 1x1 case ran in %g seconds\n", nSeconds);
printf(" Size of table == %d x %d\n", xMax, yMax);
printf(" radius_decay_rate == %g\n", radius_decay_rate);
}
break;
}
// the "max_radius" starts at 1/2*radius_fraction the table size. To start the speculation when the radius is
// 1 / n * the table size, the constant in the log below should be n / 2. so 2 == 1/4, 3 == 1/6th,
// et c.
if(dont_speculate) {
l_speculation_start = nPasses + 1;
if ( extra_debug )printf("speculation will not be done\n");
}
else {
if(radius_fraction < 1.0 ) {
if ( extra_debug )printf("Warning: radius_fraction should be >= 1. Setting to 1.\n");
radius_fraction = 1.0;
}
l_speculation_start = (int)((double)nPasses * log(radius_fraction) / log((double)nPasses));
if ( extra_debug )printf( "We will start speculation at iteration %d\n", l_speculation_start );
}
double single_time; // for speedup calculations
for(int p = threads.first; p <= threads.last; ++p) {
// Restrict max concurrency level via task_arena interface
task_arena ta(p);
if ( extra_debug )printf( " -------------- Running with %d threads. ------------\n", p);
// run the SOM build for a series of subranges
for(xranges = 1; xranges <= xRangeMax; ++xranges) {
for(yranges = xranges; yranges <= yRangeMax; ++yranges) {
if(xranges == 1 && yranges == 1) {
// don't pointlessly speculate if we're only running one subrange.
speculation_start = nPasses + 1;
}
else {
speculation_start = l_speculation_start;
}
SOMap map1(xMax, yMax);
map1.initialize(InitializeGradient, max_range, min_range);
if(extra_debug) printf( "Start learning for [%d,%d] ----------- \n", xranges,yranges);
tick_count t0 = tick_count::now();
graph_teach(map1, my_teaching, ta);
tick_count t1 = tick_count::now();
if ( extra_debug )printf( "Done learning for [%d,%d], which took %g seconds ", xranges,yranges, (t1-t0).seconds());
if(xranges == 1 && yranges == 1) single_time = (t1-t0).seconds();
if ( extra_debug )printf( ": speedup == %g\n", single_time / (t1-t0).seconds());
} // yranges
} // xranges
} // #threads p
printf("done\n");
return 0;
}

View File

@@ -0,0 +1,314 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
522FF8DD11F573FC00A587B2 /* som_graph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 522FF8DB11F573FC00A587B2 /* som_graph.cpp */; };
522FF8DE11F573FC00A587B2 /* som.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 522FF8DC11F573FC00A587B2 /* som.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
C3C58957218B643900DAC94C /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.intel.compilers.icc.latest;
fileType = sourcecode.cpp;
isEditable = 1;
outputFiles = (
);
script = "# Type a script or drag a script file from your workspace to insert its path.\n";
};
/* End PBXBuildRule section */
/* Begin PBXCopyFilesBuildPhase section */
8DD76F690486A84900D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 12;
dstPath = "";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
522FF8DB11F573FC00A587B2 /* som_graph.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = som_graph.cpp; path = ../som_graph.cpp; sourceTree = SOURCE_ROOT; };
522FF8DC11F573FC00A587B2 /* som.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = som.cpp; path = ../som.cpp; sourceTree = SOURCE_ROOT; };
8DD76F6C0486A84900D96B5E /* som */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = som; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8DD76F660486A84900D96B5E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
08FB7794FE84155DC02AAC07 /* som */ = {
isa = PBXGroup;
children = (
08FB7795FE84155DC02AAC07 /* Source */,
1AB674ADFE9D54B511CA2CBB /* Products */,
);
name = som;
sourceTree = "<group>";
};
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
522FF8DB11F573FC00A587B2 /* som_graph.cpp */,
522FF8DC11F573FC00A587B2 /* som.cpp */,
);
name = Source;
sourceTree = "<group>";
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8DD76F6C0486A84900D96B5E /* som */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8DD76F620486A84900D96B5E /* som */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "som" */;
buildPhases = (
8DD76F640486A84900D96B5E /* Sources */,
8DD76F660486A84900D96B5E /* Frameworks */,
8DD76F690486A84900D96B5E /* CopyFiles */,
);
buildRules = (
C3C58957218B643900DAC94C /* PBXBuildRule */,
);
dependencies = (
);
name = som;
productInstallPath = "$(HOME)/bin";
productName = som;
productReference = 8DD76F6C0486A84900D96B5E /* som */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1000;
};
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "som" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,
);
mainGroup = 08FB7794FE84155DC02AAC07 /* som */;
projectDirPath = "";
projectRoot = "";
targets = (
8DD76F620486A84900D96B5E /* som */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
8DD76F640486A84900D96B5E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
522FF8DD11F573FC00A587B2 /* som_graph.cpp in Sources */,
522FF8DE11F573FC00A587B2 /* som.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
A1F593C60B8F0E6E00073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = _CONSOLE;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = som;
ZERO_LINK = NO;
};
name = Debug64;
};
A1F593C70B8F0E6E00073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PREPROCESSOR_DEFINITIONS = _CONSOLE;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = som;
ZERO_LINK = NO;
};
name = Release64;
};
A1F593C80B8F0E6E00073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(TBBROOT)/include",
/opt/intel/tbb/include,
);
ICC_CXX_LANG_DIALECT = "c++11";
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
LIBRARY_SEARCH_PATHS = (
"$(TBBROOT)/lib",
/opt/intel/tbb/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
ONLY_ACTIVE_ARCH = YES;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-m64",
);
OTHER_LDFLAGS = (
"-m64",
"-ltbb_debug",
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Debug64;
};
A1F593C90B8F0E6E00073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(TBBROOT)/include",
/opt/intel/tbb/include,
);
ICC_CXX_LANG_DIALECT = "c++11";
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
LIBRARY_SEARCH_PATHS = (
"$(TBBROOT)/lib",
/opt/intel/tbb/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-m64",
);
OTHER_LDFLAGS = (
"-m64",
"-ltbb",
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Release64;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "som" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F593C60B8F0E6E00073279 /* Debug64 */,
A1F593C70B8F0E6E00073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "som" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F593C80B8F0E6E00073279 /* Debug64 */,
A1F593C90B8F0E6E00073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View File

@@ -0,0 +1,55 @@
# Copyright (c) 2005-2020 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.
# Common Makefile that builds and runs example.
# Just specify your program basename
PROG=stereo
ARGS=
PERF_RUN_ARGS=
# Trying to find if icl.exe is set
CXX1 = $(TBB_CXX)-
CXX2 = $(CXX1:icl.exe-=icl.exe)
CXX = $(CXX2:-=cl.exe)
# TBB libs
TBBLIB=tbb.lib
TBBLIB_DEBUG=tbb_debug.lib
# OpenCL lib
OPENCL_LIB=OpenCL.lib
# The C++ compiler options
MYCXXFLAGS=/TP /EHsc /W3 /nologo /D _CONSOLE /D _MBCS /D WIN32 /D _CRT_SECURE_NO_DEPRECATE /D _CRT_SECURE_NO_WARNINGS /D _SCL_SECURE_NO_WARNINGS $(CXXFLAGS)
MYLDFLAGS=/INCREMENTAL:NO /NOLOGO /DEBUG $(LDFLAGS)
all: release test
release:
$(CXX) *.cpp /MD /O2 /D NDEBUG $(MYCXXFLAGS) /link $(TBBLIB) $(OPENCL_LIB) $(MYLDFLAGS) /OUT:$(PROG).exe
debug:
$(CXX) *.cpp /MDd /Od /Zi /D TBB_USE_DEBUG /D _DEBUG $(MYCXXFLAGS) /link $(TBBLIB_DEBUG) $(OPENCL_LIB) $(MYLDFLAGS) /OUT:$(PROG).exe
profile:
$(CXX) *.cpp /MD /O2 /Zi /D NDEBUG $(MYCXXFLAGS) /D TBB_USE_THREADING_TOOLS /link $(TBBLIB) $(OPENCL_LIB) $(MYLDFLAGS) /OUT:$(PROG).exe
clean:
@cmd.exe /C del $(PROG).exe *.obj *.?db *.manifest
test:
$(PROG) $(ARGS)
compiler_check:
@$(CXX) >nul 2>&1 || echo "$(CXX) command not found. Check if CXX=$(CXX) is set properly"
perf_build: release
perf_run:
$(PROG) $(PERF_RUN_ARGS)

View File

@@ -0,0 +1,52 @@
/*
Copyright (c) 2005-2020 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.
*/
__constant int redChannelOffset = 0;
__constant int greenChannelOffset = 1;
__constant int blueChannelOffset = 2;
__constant int channelsPerPixel = 4;
__constant uint channelIncreaseValue = 10;
__kernel void mergeImages( __global uchar* bufferLeft, __global uchar* bufferRight, uint width) {
const int indexWidth = get_global_id(0);
const int indexHeight = get_global_id(1);
const int pixelIndex = channelsPerPixel * width * indexHeight + channelsPerPixel * indexWidth;
const int pixelGreenChannelIndex = pixelIndex + greenChannelOffset;
const int pixelBlueChannelIndex = pixelIndex + blueChannelOffset;
bufferLeft[pixelGreenChannelIndex] = (bufferRight[pixelGreenChannelIndex] + bufferLeft[pixelGreenChannelIndex]) / 2;
bufferLeft[pixelBlueChannelIndex] = bufferRight[pixelBlueChannelIndex];
}
__kernel void applyLeftImageEffect( __global uchar* bufferLeft, uint width) {
const int indexWidth = get_global_id(0);
const int indexHeight = get_global_id(1);
const int pixelRedChannelIndex = channelsPerPixel * width * indexHeight + channelsPerPixel * indexWidth + redChannelOffset;
bufferLeft[pixelRedChannelIndex] = convert_uchar_sat(bufferLeft[pixelRedChannelIndex] + channelIncreaseValue);
}
__kernel void applyRightImageEffect( __global uchar* bufferRight, uint width) {
const int indexWidth = get_global_id(0);
const int indexHeight = get_global_id(1);
const int pixelBlueChannelIndex = channelsPerPixel * width * indexHeight + channelsPerPixel * indexWidth + blueChannelOffset;
bufferRight[pixelBlueChannelIndex] = convert_uchar_sat(bufferRight[pixelBlueChannelIndex] + channelIncreaseValue);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,445 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks. Stereo sample</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,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
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks.<br>Stereo sample</h1>
</div>
<p>
The Stereo example is an implementation of the algorithm that applies stereoscopic 3D effect on two input images and achieved by means of encoding each eye's image using filters of different colors: red and blue -
<a href="http://en.wikipedia.org/wiki/Anaglyph_3D"><i>Anaglyph effect</i></a>.
<br><br>
The example uses the flow graph interface and can be executed both on CPU and GPU for image processing.
The output of this application is a PNG image with the anaglyph effect applied.
<br><br>
<i>
This example includes software developed by Lode Vandevenne. See
<a href="#copyright">here</a> for copyright information.
</i>
<br>
It exemplifies the opencl_node usage in the flow graph interface in context of creating a stereo image from two input images.
<br><br>
This example uses C++11 lambda expressions. Specifying a compiler option such as -std=c++11 or similar might be necessary in order to build the example.
For more information please refer to the documentation for the compiler you use.
</p>
<div class="changes">
<div class="h3-alike">System Requirements</div>
<input type="checkbox">
<div class="show-hide">
<p>
For the most up to date system requirements, see the <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a>
</p>
<p>
Additionally, you have to install OpenCL&trade; version 1.2 or higher in order to run this example. See the <a href="https://software.intel.com/en-us/articles/opencl-drivers">OpenCL&trade; Drivers and Runtimes for Intel&reg; Architecture</a>.
</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Files</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="stereo.cpp">stereo.cpp</a>
<dd>The implementation of stereo image creation algorithm based on the flow graph interface.
<dt><a href="lodepng.cpp">lodepng.cpp</a>
<dd>Library for reading and writing png images.
<dt><a href="lodepng.h">lodepng.h</a>
<dd>Public header file for the lodepng library.
<dt><a href="utils.h">utils.h</a>
<dd>Support functions for this example.
<dt><a href="imageEffects.cl">imageEffects.cl</a>
<dd>OpenCL kernel file with image effects algorithms.
<dt><a href="Makefile">Makefile</a>
<dd>Makefile for building the example.
</dl>
</div>
</div>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="msvs/">msvs</a>
<dd>Contains Microsoft* Visual Studio* workspace for building and running the example (Windows* systems only).
<dt><a href="xcode/">xcode</a>
<dd>Contains Xcode* IDE workspace for building and running the example (macOS* systems only).
</dl>
<p>For information about the minimum supported version of IDE, see <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a></p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Build instructions</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<p>General build directions can be found <a href="../../index.html">here</a>.</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Usage</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><tt>stereo <i>-h</i></tt>
<dd>Prints the help for command line options
<dt><tt>stereo [<i>-v</i>] [<i>-alg</i>=value] [<i>first_filename</i>] [<i>second_filename</i>]</tt>
<dd><i>-v</i> print diagnostic output to screen<br>
<i>-alg</i> name of the used pipeline realization - can be host, target (default) or host_target<br>
<i>first_filename</i> first input file name<br>
<i>second_filename</i> second input file name<br>
</dl>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a>
<hr>
<a name="copyright"></a>
<div class="changes">
<div class="h3-alike">Legal Information</div>
<input type="checkbox">
<div class="show-hide">
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
<p>
LodePNG version 20160409
Copyright (c) 2005-2016 Lode Vandevenne
</p>
<p>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
<br>
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
<ol>
<li>The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
<li>Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
<li>This notice may not be removed or altered from any source
distribution.
</ol>
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,437 @@
/*
Copyright (c) 2005-2020 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 TBB_PREVIEW_FLOW_GRAPH_NODES 1
#define TBB_PREVIEW_FLOW_GRAPH_FEATURES 1
#include "tbb/tbb_config.h"
#include "../../common/utility/utility.h"
#if __TBB_PREVIEW_OPENCL_NODE && __TBB_CPP11_LAMBDAS_PRESENT
#if _MSC_VER
// suppress warning C4503: decorated name length exceeded, name was truncated
#pragma warning(disable : 4503)
#endif
#include <iostream>
#include "tbb/flow_graph.h"
#include "tbb/flow_graph_opencl_node.h"
#include "tbb/tick_count.h"
#include "utils.h"
static const int redChannelOffset = 0;
static const int greenChannelOffset = 1;
static const int blueChannelOffset = 2;
static const int channelsPerPixel = 4;
static const unsigned int channelIncreaseValue = 10;
void applyLeftImageEffect(utils::image_buffer& image) {
const int heighBase = channelsPerPixel * image.width;
std::vector<unsigned char>& buffer = *image.buffer;
// Increase the Red channel of left image by 10
for (unsigned int y = 0; y < image.height; y++) {
const int heightOffset = heighBase * y;
for (unsigned int x = 0; x < image.width; x++) {
int pixelOffset = heightOffset + channelsPerPixel * x + redChannelOffset;
unsigned int pixelValue = buffer[pixelOffset] + channelIncreaseValue;
buffer[pixelOffset] = utils::convert_uchar_sat(pixelValue);
}
}
}
void applyRightImageEffect(utils::image_buffer& image) {
const int heighBase = channelsPerPixel * image.width;
std::vector<unsigned char>& buffer = *image.buffer;
// Increase the Blue channel of left image by 10
for (unsigned int y = 0; y < image.height; y++) {
const int heightOffset = heighBase * y;
for (unsigned int x = 0; x < image.width; x++) {
const int pixelOffset = heightOffset + channelsPerPixel * x + blueChannelOffset;
unsigned int pixelValue = buffer[pixelOffset] + channelIncreaseValue;
buffer[pixelOffset] = utils::convert_uchar_sat(pixelValue);
}
}
}
// This function merges to image buffers into the first buffer (leftImageBuffer as a destination)
void mergeImageBuffers(utils::image_buffer& leftImage, const utils::image_buffer& rightImage) {
const int heighBase = channelsPerPixel * leftImage.width;
std::vector<unsigned char>& leftImageBuffer = *leftImage.buffer;
std::vector<unsigned char>& rightImageBuffer = *rightImage.buffer;
// Apply stereoscopic merge using algorithm: R: left image, G: left and right images (middle value), B: right image
for (unsigned int y = 0; y < leftImage.height; y++) {
const int heightOffset = heighBase * y;
for (unsigned int x = 0; x < leftImage.width; x++) {
const int pixelOffset = heightOffset + channelsPerPixel * x;
const int greenChannelIndex = pixelOffset + greenChannelOffset;
const int blueChannelIndex = pixelOffset + blueChannelOffset;
const int middleGreenChannel = (leftImageBuffer[greenChannelIndex] + rightImageBuffer[greenChannelIndex]);
leftImageBuffer[greenChannelIndex] = middleGreenChannel / 2;
leftImageBuffer[blueChannelIndex] = rightImageBuffer[blueChannelIndex];
}
}
}
void fillOpenclBuffer(tbb::flow::opencl_buffer<cl_uchar>& openclBuffer, const std::vector<unsigned char>& sourceBuffer) {
std::copy(sourceBuffer.begin(), sourceBuffer.end(), openclBuffer.begin());
}
class gpu_device_selector {
public:
template <typename DeviceFilter>
tbb::flow::opencl_device operator()(tbb::flow::opencl_factory<DeviceFilter>& f) {
// Set your GPU device if available to execute kernel on
const tbb::flow::opencl_device_list &devices = f.devices();
tbb::flow::opencl_device_list::const_iterator it = std::find_if(
devices.cbegin(), devices.cend(),
[](const tbb::flow::opencl_device &d) {
cl_device_type type;
d.info(CL_DEVICE_TYPE, type);
return CL_DEVICE_TYPE_GPU == type;
});
if (it == devices.cend()) {
std::cout << "Info: could not find any GPU devices. Choosing the first available device (default behaviour)." << std::endl;
return *(f.devices().begin());
} else {
// Return GPU device from factory
return *it;
}
}
};
// Image processing function that is executed on CPU only
void hostFunction(const std::string& firstFile, const std::string& secondFile, const std::string& outputFile) {
using namespace tbb::flow;
typedef tuple< utils::image_buffer, utils::image_buffer > MergeImagesTuple;
graph g;
function_node< std::string, utils::image_buffer > fileReaderOne(g, serial, [](const std::string& fileToRead) -> utils::image_buffer {
return utils::getOrGenerateImage(fileToRead);
});
function_node< std::string, utils::image_buffer > fileReaderTwo = fileReaderOne;
function_node< utils::image_buffer, utils::image_buffer > leftImageEffect(g, unlimited, [](utils::image_buffer image) -> utils::image_buffer {
applyLeftImageEffect(image);
return image;
});
function_node< utils::image_buffer, utils::image_buffer > rightImageEffect(g, unlimited, [](utils::image_buffer image) -> utils::image_buffer {
applyRightImageEffect(image);
return image;
});
join_node< tuple< utils::image_buffer, utils::image_buffer > > joinNode(g);
function_node< MergeImagesTuple, utils::image_buffer > mergeImages(g, unlimited, [](const MergeImagesTuple& bufferTuple) -> utils::image_buffer {
// Two input images from tuple are merged into the first image,
utils::image_buffer leftImageBuffer = std::get<0>(bufferTuple);
utils::image_buffer rightImageBuffer = std::get<1>(bufferTuple);
mergeImageBuffers(leftImageBuffer, rightImageBuffer);
return leftImageBuffer;
});
function_node< utils::image_buffer > outputWriter(g, unlimited, [&outputFile](const utils::image_buffer& image) {
utils::writePNGImage(image, outputFile);
});
// Read left image
make_edge(fileReaderOne, leftImageEffect);
// Read right image
make_edge(fileReaderTwo, rightImageEffect);
// Process left image
make_edge(leftImageEffect, tbb::flow::input_port<0>(joinNode));
// Process right image
make_edge(rightImageEffect, tbb::flow::input_port<1>(joinNode));
// Merge images
make_edge(joinNode, mergeImages);
make_edge(mergeImages, outputWriter);
// Start graph image processing
fileReaderOne.try_put(firstFile);
fileReaderTwo.try_put(secondFile);
g.wait_for_all();
}
// Image processing function using OpenCL
/** Reading and writing image to file is executed on CPU, while all buffers manipulation are executed on GPU */
void openclFunctionGPU(const std::string& firstFile, const std::string& secondFile, const std::string& outputFile) {
using namespace tbb::flow;
typedef opencl_buffer<cl_uchar> OpenclImageBuffer;
typedef std::array<unsigned int, 2> NDRange;
typedef tuple< OpenclImageBuffer, cl_uint, NDRange > OpenclImageTuple;
typedef tuple< OpenclImageBuffer, OpenclImageBuffer, cl_uint, NDRange > OpenclImagesMergeTuple;
typedef tuple< OpenclImageBuffer, NDRange > WriteImageBufferTuple;
graph g;
gpu_device_selector gpu_selector;
function_node< std::string, OpenclImageTuple > fileReaderOne(g, serial, [&g](const std::string& fileToRead) -> OpenclImageTuple {
utils::image_buffer src = utils::getOrGenerateImage(fileToRead);
// Create and initialize opencl_buffer in order to pass it to kernel
OpenclImageBuffer oclImage(src.buffer->size());
fillOpenclBuffer(oclImage, *src.buffer);
NDRange rangeList = { src.width, src.height };
return std::make_tuple(oclImage, src.width, rangeList);
});
function_node< std::string, OpenclImageTuple > fileReaderTwo = fileReaderOne;
split_node< OpenclImageTuple > splitArgumentsLeftNode(g);
// Kernel should be in the current folder
opencl_program<> program("imageEffects.cl");
opencl_node< OpenclImageTuple > leftImageEffect(g, program.get_kernel("applyLeftImageEffect"), gpu_selector);
split_node< OpenclImageTuple > splitArgumentsRightNode(g);
opencl_node< OpenclImageTuple > rightImageEffect(g, program.get_kernel("applyRightImageEffect"), gpu_selector);
opencl_node< OpenclImagesMergeTuple > mergeImages(g, program.get_kernel("mergeImages"), gpu_selector);
join_node< WriteImageBufferTuple > joinTupleNode(g);
function_node< WriteImageBufferTuple > outputWriter(g, unlimited, [&outputFile](const WriteImageBufferTuple& image) {
// The result image have to be copied in order to be changed,
// the second parameter - image size, can be taken by const reference
OpenclImageBuffer imageBuffer = std::get<0>(image);
const NDRange& imageSize = std::get<1>(image);
unsigned int width = imageSize[0];
unsigned int height = imageSize[1];
utils::writePNGImage(imageBuffer.data(), width, height, outputFile);
});
// Process left image
make_edge(fileReaderOne, splitArgumentsLeftNode);
make_edge(output_port<0>(splitArgumentsLeftNode), input_port<0>(leftImageEffect));
make_edge(output_port<1>(splitArgumentsLeftNode), input_port<1>(leftImageEffect));
// Pass OpenCL NDRange via input port because it depends on input data
make_edge(output_port<2>(splitArgumentsLeftNode), input_port<2>(leftImageEffect));
// Process right image
make_edge(fileReaderTwo, splitArgumentsRightNode);
make_edge(output_port<0>(splitArgumentsRightNode), input_port<0>(rightImageEffect));
make_edge(output_port<1>(splitArgumentsRightNode), input_port<1>(rightImageEffect));
// Pass OpenCL NDRange via input port because it depends on input data
make_edge(output_port<2>(splitArgumentsRightNode), input_port<2>(rightImageEffect));
// Merge images
make_edge(output_port<0>(leftImageEffect), input_port<0>(mergeImages));
make_edge(output_port<0>(rightImageEffect), input_port<1>(mergeImages));
make_edge(output_port<1>(leftImageEffect), input_port<2>(mergeImages));
// Set OpenCL NDRange here (because the values may vary, depending on input data)
make_edge(output_port<2>(leftImageEffect), input_port<3>(mergeImages));
// Write image to PNG
make_edge(output_port<0>(mergeImages), input_port<0>(joinTupleNode));
make_edge(output_port<3>(mergeImages), input_port<1>(joinTupleNode));
make_edge(joinTupleNode, outputWriter);
// Define where to get ndrange and kernel arguments
leftImageEffect.set_args(port_ref<0, 1>());
leftImageEffect.set_range(port_ref<2>());
rightImageEffect.set_args(port_ref<0, 1>());
rightImageEffect.set_range(port_ref<2>());
mergeImages.set_args(port_ref<0, 2>());
mergeImages.set_range(port_ref<3>());
// Start graph image processing pipeline
fileReaderOne.try_put(firstFile);
fileReaderTwo.try_put(secondFile);
g.wait_for_all();
}
// Second image processing function using OpenCL
/** Reading and writing image to file is executed on CPU, while some buffers manipulation are executed on GPU
and others runs on CPU device. This case should have the best performance among others. */
void openclFunctionGPUPlusCPU(const std::string& firstFile, const std::string& secondFile, const std::string& outputFile) {
using namespace tbb::flow;
typedef opencl_buffer<cl_uchar> OpenclImageBuffer;
typedef std::array<unsigned int, 2> NDRange;
typedef tuple< OpenclImageBuffer, cl_uint, NDRange > OpenclImageTuple;
typedef tuple< OpenclImageBuffer, OpenclImageBuffer, cl_uint, NDRange > OpenclImagesMergeTuple;
typedef tuple< OpenclImageBuffer, NDRange > WriteImageBufferTuple;
graph g;
gpu_device_selector gpu_selector;
function_node< std::string, OpenclImageTuple > fileReaderOne(g, serial, [&g](const std::string& fileToRead) -> OpenclImageTuple {
utils::image_buffer src = utils::getOrGenerateImage(fileToRead);
// Create and initialize opencl_buffer in order to pass it to mergeImages kernel
OpenclImageBuffer oclImage(src.buffer->size());
fillOpenclBuffer(oclImage, *src.buffer);
NDRange rangeList = { src.width, src.height };
return std::make_tuple(oclImage, src.width, rangeList);
});
function_node< std::string, utils::image_buffer > fileReaderTwo(g, serial, [](const std::string& fileToRead) -> utils::image_buffer {
return utils::readPNGImage(fileToRead);
});
split_node< OpenclImageTuple > splitArgumentsLeftNode(g);
// Kernel should be in the current folder
opencl_program<> program("imageEffects.cl");
opencl_node< OpenclImageTuple > leftImageEffect(g, program.get_kernel("applyLeftImageEffect"), gpu_selector);
function_node< utils::image_buffer, OpenclImageBuffer > rightImageEffect(g, unlimited, [&g](utils::image_buffer image) -> OpenclImageBuffer {
applyRightImageEffect(image);
// Create and initialize opencl_buffer in order to pass it to kernel
OpenclImageBuffer oclImage(image.buffer->size());
fillOpenclBuffer(oclImage, *image.buffer);
return oclImage;
});
opencl_node< OpenclImagesMergeTuple > mergeImages(g, program.get_kernel("mergeImages"), gpu_selector);
join_node< WriteImageBufferTuple > joinTupleNode(g);
function_node< WriteImageBufferTuple > outputWriter(g, unlimited, [&outputFile](const WriteImageBufferTuple& image) {
// The result image have to be copied in order to be changed,
// the second parameter - image size, can be taken by const reference
OpenclImageBuffer imageBuffer = std::get<0>(image);
const NDRange& imageSize = std::get<1>(image);
unsigned int width = imageSize[0];
unsigned int height = imageSize[1];
utils::writePNGImage(imageBuffer.data(), width, height, outputFile);
});
// Process left image on GPU
make_edge(fileReaderOne, splitArgumentsLeftNode);
make_edge(output_port<0>(splitArgumentsLeftNode), input_port<0>(leftImageEffect));
make_edge(output_port<1>(splitArgumentsLeftNode), input_port<1>(leftImageEffect));
// Pass OpenCL NDRange via input port because it depends on input data
make_edge(output_port<2>(splitArgumentsLeftNode), input_port<2>(leftImageEffect));
// Process right image on CPU
make_edge(fileReaderTwo, rightImageEffect);
// Merge images on GPU
make_edge(output_port<0>(leftImageEffect), input_port<0>(mergeImages));
make_edge(rightImageEffect, input_port<1>(mergeImages));
make_edge(output_port<1>(leftImageEffect), input_port<2>(mergeImages));
// Pass OpenCL NDRange via input port because it depends on input data
make_edge(output_port<2>(leftImageEffect), input_port<3>(mergeImages));
// Write image to PNG
make_edge(output_port<0>(mergeImages), input_port<0>(joinTupleNode));
make_edge(output_port<3>(mergeImages), input_port<1>(joinTupleNode));
make_edge(joinTupleNode, outputWriter);
// Define where to get ndrange and kernel arguments
leftImageEffect.set_args(port_ref<0, 1>());
leftImageEffect.set_range(port_ref<2>());
mergeImages.set_args(port_ref<0, 2>());
mergeImages.set_range(port_ref<3>());
// Start graph image processing pipeline
fileReaderOne.try_put(firstFile);
fileReaderTwo.try_put(secondFile);
g.wait_for_all();
}
int main(int argc, char* argv[]) {
try {
tbb::tick_count mainStartTime = tbb::tick_count::now();
bool verbose = false;
std::string algVersion;
std::string inputFileFirst;
std::string inputFileSecond;
std::string outputFile = "output.png";
utility::parse_cli_arguments(argc, argv,
utility::cli_argument_pack()
//"-h" option for displaying help
.arg(verbose, "-v", "verbose mode")
.arg(algVersion, "-alg", "name of the used pipeline realisation - can be host, target (default) or host_target")
.positional_arg(inputFileFirst, "first_filename", "first input file name")
.positional_arg(inputFileSecond, "second_filename", "second input file name")
);
if (!utils::isBothImagesExists(inputFileFirst, inputFileSecond)) {
std::cout << "Info: one or both images does not exists or empty. Input images will be generated instead." << std::endl;
inputFileFirst.clear();
inputFileSecond.clear();
} else {
std::cout << "First input file name: " << inputFileFirst << std::endl;
std::cout << "Second input file name: " << inputFileSecond << std::endl;
}
if (algVersion.empty() || algVersion == "target") {
openclFunctionGPU(inputFileFirst, inputFileSecond, outputFile);
} else if (algVersion == "host_target") {
openclFunctionGPUPlusCPU(inputFileFirst, inputFileSecond, outputFile);
} else if (algVersion == "host") {
hostFunction(inputFileFirst, inputFileSecond, outputFile);
}
utility::report_elapsed_time((tbb::tick_count::now() - mainStartTime).seconds());
return 0;
} catch (std::exception& e) {
std::cerr << "Error occurred :\"" << e.what() << "\"\n";
return -1;
}
}
#else
int main() {
utility::report_skipped();
return 0;
}
#endif /* __TBB_PREVIEW_OPENCL_NODE && __TBB_CPP11_LAMBDAS_PRESENT */

View File

@@ -0,0 +1,104 @@
/*
Copyright (c) 2005-2020 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 <iostream>
#include <string>
#include "lodepng.h"
namespace utils {
inline unsigned char convert_uchar_sat(unsigned int v) {
return static_cast<unsigned char>(v < UCHAR_MAX ? v : UCHAR_MAX);
}
struct image_buffer {
unsigned int width, height;
std::shared_ptr< std::vector<unsigned char> > buffer; // smart pointer to the vector of raw pixels in RGBA format, 4 bytes per pixel
};
image_buffer readPNGImage(const std::string& imageName) {
image_buffer image;
image.buffer = std::make_shared< std::vector<unsigned char> >();
unsigned int error = lodepng::decode(*image.buffer, image.width, image.height, imageName.c_str());
if (error) {
std::string exceptionMessage = "decoder error: " + std::string(lodepng_error_text(error));
throw std::runtime_error(exceptionMessage);
}
return image;
}
void readPNGImage(unsigned char* imageBuffer, unsigned int& width, unsigned int& height, const char* imageName) {
unsigned int error = lodepng_decode32_file(&imageBuffer, &width, &height, imageName);
if (error) {
std::string exceptionMessage = "decoder error: " + std::string(lodepng_error_text(error));
throw std::runtime_error(exceptionMessage);
}
}
void writePNGImage(const image_buffer& image, const std::string& outputFile) {
unsigned int error = lodepng::encode(outputFile, *image.buffer, image.width, image.height);
if (error) {
std::string exceptionMessage = "encoder error: " + std::string(lodepng_error_text(error));
throw std::runtime_error(exceptionMessage);
}
}
void writePNGImage(unsigned char* imageBuffer, unsigned int& width, unsigned int& height, const std::string& outputFile) {
unsigned int error = lodepng::encode(outputFile, imageBuffer, width, height);
if (error) {
std::string exceptionMessage = "encoder error: " + std::string(lodepng_error_text(error));
throw std::runtime_error(exceptionMessage);
}
}
image_buffer generatePNGImage() {
image_buffer image;
image.width = 1024;
image.height = 1024;
image.buffer = std::make_shared< std::vector<unsigned char> >(image.width * image.height * 4);
std::vector<unsigned char>& buffer = *image.buffer;
const int widthOffset = 4 * image.width;
for (unsigned y = 0; y < image.height; y++) {
for (unsigned x = 0; x < image.width; x++) {
const int pixelOffset = widthOffset * y + 4 * x;
buffer[pixelOffset] = 200 * !(x & y);
buffer[pixelOffset + 1] = x ^ y;
buffer[pixelOffset + 2] = x | y;
buffer[pixelOffset + 3] = 255;
}
}
return image;
}
bool isFileExist(const std::string& fileName) {
std::ifstream file(fileName);
return file.good();
}
bool isBothImagesExists(const std::string& firstFile, const std::string& secondFile) {
return isFileExist(firstFile) && isFileExist(secondFile);
}
image_buffer getOrGenerateImage(const std::string& fileName) {
return fileName.empty() ? generatePNGImage() : readPNGImage(fileName);
}
}

View File

@@ -0,0 +1,324 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
8415B6821CFC8B7F00A875B5 /* stereo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8415B6801CFC8B7F00A875B5 /* stereo.cpp */; };
8415B6881CFC8B9200A875B5 /* lodepng.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8415B6851CFC8B9200A875B5 /* lodepng.cpp */; };
8415B68A1CFC96D900A875B5 /* OpenCL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8415B6891CFC96D900A875B5 /* OpenCL.framework */; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
C3C58958218B657900DAC94C /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.intel.compilers.icc.latest;
fileType = sourcecode.cpp;
isEditable = 1;
outputFiles = (
);
script = "# Type a script or drag a script file from your workspace to insert its path.\n";
};
/* End PBXBuildRule section */
/* Begin PBXCopyFilesBuildPhase section */
8DD76F690486A84900D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 12;
dstPath = "";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
8415B6801CFC8B7F00A875B5 /* stereo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stereo.cpp; path = ../stereo.cpp; sourceTree = "<group>"; };
8415B6831CFC8B9200A875B5 /* imageEffects.cl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.opencl; name = imageEffects.cl; path = ../imageEffects.cl; sourceTree = "<group>"; };
8415B6851CFC8B9200A875B5 /* lodepng.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lodepng.cpp; path = ../lodepng.cpp; sourceTree = "<group>"; };
8415B6861CFC8B9200A875B5 /* lodepng.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lodepng.h; path = ../lodepng.h; sourceTree = "<group>"; };
8415B6891CFC96D900A875B5 /* OpenCL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenCL.framework; path = System/Library/Frameworks/OpenCL.framework; sourceTree = SDKROOT; };
8DD76F6C0486A84900D96B5E /* Stereo */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Stereo; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8DD76F660486A84900D96B5E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8415B68A1CFC96D900A875B5 /* OpenCL.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
08FB7794FE84155DC02AAC07 /* Stereo */ = {
isa = PBXGroup;
children = (
8415B6891CFC96D900A875B5 /* OpenCL.framework */,
08FB7795FE84155DC02AAC07 /* Source */,
1AB674ADFE9D54B511CA2CBB /* Products */,
);
name = Stereo;
sourceTree = "<group>";
};
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
8415B6831CFC8B9200A875B5 /* imageEffects.cl */,
8415B6851CFC8B9200A875B5 /* lodepng.cpp */,
8415B6861CFC8B9200A875B5 /* lodepng.h */,
8415B6801CFC8B7F00A875B5 /* stereo.cpp */,
);
name = Source;
sourceTree = "<group>";
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8DD76F6C0486A84900D96B5E /* Stereo */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8DD76F620486A84900D96B5E /* Stereo */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "Stereo" */;
buildPhases = (
8DD76F640486A84900D96B5E /* Sources */,
8DD76F660486A84900D96B5E /* Frameworks */,
8DD76F690486A84900D96B5E /* CopyFiles */,
);
buildRules = (
C3C58958218B657900DAC94C /* PBXBuildRule */,
);
dependencies = (
);
name = Stereo;
productInstallPath = "$(HOME)/bin";
productName = Stereo;
productReference = 8DD76F6C0486A84900D96B5E /* Stereo */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1000;
};
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "stereo" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,
);
mainGroup = 08FB7794FE84155DC02AAC07 /* Stereo */;
projectDirPath = "";
projectRoot = "";
targets = (
8DD76F620486A84900D96B5E /* Stereo */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
8DD76F640486A84900D96B5E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8415B6881CFC8B9200A875B5 /* lodepng.cpp in Sources */,
8415B6821CFC8B7F00A875B5 /* stereo.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
A1F593C60B8F0E6E00073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = Stereo;
ZERO_LINK = NO;
};
name = Debug64;
};
A1F593C70B8F0E6E00073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "$(inherited)";
ICC_CXX_LANG_DIALECT = "c++11";
INSTALL_PATH = "$(HOME)/bin";
LD_RUNPATH_SEARCH_PATHS = "$(inherited)";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_NAME = Stereo;
ZERO_LINK = NO;
};
name = Release64;
};
A1F593C80B8F0E6E00073279 /* Debug64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(TBBROOT)/include",
/opt/intel/tbb/include,
);
ICC_CXX_LANG_DIALECT = "c++11";
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
LIBRARY_SEARCH_PATHS = (
"$(TBBROOT)/lib",
/opt/intel/tbb/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
ONLY_ACTIVE_ARCH = YES;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-m64",
);
OTHER_LDFLAGS = (
"-m64",
"-ltbb_debug",
"-framework",
OpenCL,
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Debug64;
};
A1F593C90B8F0E6E00073279 /* Release64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_ENABLE_CPP_RTTI = YES;
GCC_MODEL_TUNING = "";
GCC_NO_COMMON_BLOCKS = YES;
GCC_VERSION = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(TBBROOT)/include",
/opt/intel/tbb/include,
);
ICC_CXX_LANG_DIALECT = "c++11";
LD_RUNPATH_SEARCH_PATHS = "$(TBBROOT)/lib /opt/intel/tbb/lib";
LIBRARY_SEARCH_PATHS = (
"$(TBBROOT)/lib",
/opt/intel/tbb/lib,
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-m64",
);
OTHER_LDFLAGS = (
"-m64",
"-ltbb",
"-framework",
OpenCL,
);
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SYMROOT = "/tmp/tbb-$(USER)";
VALID_ARCHS = x86_64;
};
name = Release64;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "Stereo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F593C60B8F0E6E00073279 /* Debug64 */,
A1F593C70B8F0E6E00073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "stereo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A1F593C80B8F0E6E00073279 /* Debug64 */,
A1F593C90B8F0E6E00073279 /* Release64 */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release64;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View File

@@ -0,0 +1,581 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks Samples</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEMAAAAsCAYAAAA+aAX8AAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAALiIAAC4iAari3ZIAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVh
ZHlxyWU8AAAIN0lEQVRoQ+WaCaxdUxSGW2ouatZWaVS15nkqkZhSVERQglLEPCam1BCixhqqCKUS
NIiYpxhqHmouIeaY5ylFzA/v1fev8+/j3N5737v3vtf3buNP/uy9/7X2Ovuse4a997m9mgltbW2L
wRHwcHgFfAx+AH+GCb/BT2fNmvUk5ZXwYOrrOsTcCU5CJ74pPBJeA5+Bn8LfOLmagf/f8Af4NrwD
ngg3wdTHh2pOMMB1Gejx8AE4M85mNqD/A7+D78GXkXQFTIMPwUfhdPg6/AxWTRw29b8QruPD9zwY
zPrwHPi2xxmg3QrfgDfD05BGU24EB1HvC3s7REXgtwDsDzeEY+Ak+AJsUfwE2sJdcBN37V4whiU4
+KGUM2JEBtpzUInZEa5g9y4FcYfAo+GLPmwOND2HFrXrnAUHWgnq0vzDB2+Bt0H9coPs1m3gmNvD
ZyITBu234Jp26XoQfCC80sfTAXVv7wOXskuPgnHoSvnTw9P49MDdyOauAQEXhWdC4Vd4ARxmc1OB
cW0Gv3U+lJDvKFa0ufMg4GXwR3gs7J57sRNoaWnR2+znLB2RkKds6jwItvbckIQiGO+eTkSby71t
qh100qtsUCJxmmpSw5i2gWebR1jWm2047T1gf0vyfViJEKi/TtHua7wMdNJs8U/zDzjUpqYA47k4
O704wY+kUZ2P+glQc5ldac9j323sF1cH2EB6h8BxYZdbRDeDOJ16UBJiHDFuMMdYbhjEGA8DxJ4h
jXIemmMpz6ccqbZ1JUlT/3SrHC+9XeB0MjzV9RHqKFAXVg2nBkH/lxxO8aZYbhjEKEuGQH1BuCKc
z1IAN61jAtiut1wZ+ByIkwa6r9t6ZmhSFZw9eL0gxiMw4SLLDYMYFZNRDbhpcpgwzXI5MOqSEvKM
Ue8D+xU4r/Xe+C8HB1ThkhFgNqAXk6FVqyZuA1LcItBXQd+WUvf6YMslwFZvMs7KvMP/SculwKa3
hfYPPsZpfsvS9QD9PRHbcOmUC9J+H2qfoRJ/0MHgFhHIQC8mQ8twxZ0Ji099vSGegn/TP0BdD/Db
Ycn0nna9yZiceQcetFwKDE/4oNtZCtDeXHoC7dWlU1Uyvs7U6sBHJ7FaBAPU82TYJUAzFnCU+1mq
COyfwGLi6k3G05l34BrL/wFxjA/0mKUcaNqBKiJODHclQ3sLCVqZprfEvVCLtThhiskRDFAvXhnv
QPlfi5uW7ytTL14Nr0Bd1pfDXy1Lv93h6koGLstCLR/SuPJ5SQBBD8hPZATbWs6BrdZk7B4dDNpT
Mjkw3bL0YjLOsxygPUWDyExtD1GNV6JAeyTUBlDCKtbrScYxhfjyj1s+B9o+dnifIj94AnpNyaC9
f3QwkNJCTnjOsvRiMi6xrHiaA3ycyYFNbcqBpisl/aoHWaspGdg03uIc43mb/gOilt3CREslQG80
GedmlkC1KyNPBnU9wOPWMp6Aut0S74HfwIQJ7ldTMjBPdBIiGWC0TRkQlseWNmR2tlwC9DmZjEmW
pQ/zOAKqtwdcrnW/DpOBPtp9Ii6F9lhL1yWIo2zUvVhxzYHeLVcG/QfT/iuTA3qwan+zGndVP8p2
k4G8E/wLW4D6PxTlnxgwaDEjaMe6n+USYOvqZKTbUrjQcor3ZSYHRtjULvCrmgwkfY5oRc9B+3Cb
S4FhIhS+gAtZLgH9Y6GWuQU6mwx9IEqYajlA+47CsZ6lGovFBDTNkA9xM4CmpXsAWySDUrPjqZQl
QBsfnSoB41UKAvS9ouJmDfpaDpTQ2WRcXYinCZm+pdyEtDClPgLloP0unABPp3lrpoZ+KkWskSgP
sVZMhlat2t7LQftE2aoCh0sVBOheXclyCYjTp7W19bUsZAQtJuPLTA39gOhg0D7PJtny1xj1tWA+
sUpAG2j7mZaqAh9tzPSVP+XStL+w/qY1XRlfWdOSYXvp7QKnU6Ayqk4jLZcB2zD4gv1iu52qkvG5
NKPsyrCuPs9aDtDeDr4EtS7RRyXNCgfYLPtYfoC33D0Hul6tE6jOfvsMhVqaT8PWG85PXR+WxlOP
pHUIHPNXDsif7NWAT773STdlX6vK4ebi4WRgWybZqFe86tBXUAw4BL+S7UTautTXo9yFcjdKPbsq
PuQTsKdbZ16YLzZrAgdRRvXLCF/Big/R/wXInn5dffdMt8opNs214Bz6cyqNbUDRcZwTIWjDt3m+
XtcBxq3pvL6p6mFftlFUE+i8JPxRCRGoawVbcVepGcF4V4eTGPNPHv+7NjUGAhzmQOl20fyhphlg
T4CxLcQw9WC9Gxb3P4Q37NY4CHJXCuhSW3JnwEXs0qNgSHqVbw210ZP2XwK0A65/6C6NgziaAU5X
wCIUHB4H86227gKH1+JtL3gd1N5sCdACbgZo5rtgnQKx+hLs/ixsdjBXBd2TtyKNhUOp1/dprgMQ
rx9x16fcn1KbttrIyf9OkICWw1KApvY2YyXbpSBobKf7OGXApFtI+5d3Qq1BDoL6V87GcDVc9Ivq
E4D+bjTQbc1i9demreDu8Ch0ffG6hdnmDMrvFbsSsAXczIGk3fwb4VYe+pwBB9Angkd83ADtqgkq
AjetdTTV1icDlfl+Qi3AP4elHEjaDXscHgFjPdNt4ID6S9B9sNLiKoelmuFuJbCpDJi+hvqz2qFw
iIfWc2AQusxPgvq484vH2eUgtpYHH0Hteeqb75ZwMQ+j+cDg9PlwFDwd6o9sr0KtbWI/tSPgp32M
76H+s6mNX3030df5neGq1OtbZDUbOIlFoFaha0L9j0qfCHeAerDqVtODU8+hNThZfR1fHHbpG6kx
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks Samples</h1>
</div>
<p>
This directory includes example usages of Intel&reg; Threading Building Blocks (Intel&reg; TBB).
</p>
<div class="changes">
<div class="h3-alike">System Requirements:</div>
<input type="checkbox">
<div class="show-hide">
<p>
For the most up to date system requirements, see the <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a>
</p>
</div>
</div>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="GettingStarted/index.html">GettingStarted</a>
<dd>Examples from the Intel TBB <a href="http://software.intel.com/en-us/tbb-tutorial">Getting&nbsp;Started&nbsp;Guide</a>.
<dt><a href="concurrent_hash_map/index.html">concurrent_hash_map</a>
<dd>Examples using <code>concurrent_hash_map</code> container.
<dt><a href="concurrent_priority_queue/index.html">concurrent_priority_queue</a>
<dd>Examples using <code>concurrent_priority_queue</code> container.
<dt><a href="graph/index.html">graph</a>
<dd>Examples using Intel TBB Flow Graph feature.
<dt><a href="parallel_do/index.html">parallel_do</a>
<dd>Examples using <code>parallel_do</code> algorithm.
<dt><a href="parallel_for/index.html">parallel_for</a>
<dd>Examples using <code>parallel_for</code> algorithm.
<dt><a href="parallel_reduce/index.html">parallel_reduce</a>
<dd>Examples using <code>parallel_reduce</code> algorithm.
<dt><a href="pipeline/index.html">pipeline</a>
<dd>Examples using <code>pipeline</code> algorithm.
<dt><a href="task/index.html">task</a>
<dd>Examples using raw <code>task</code> interface.
<dt><a href="task_group/index.html">task_group</a>
<dd>Examples using <code>task_group</code> interface.
<dt><a href="task_arena/index.html">task_arena</a>
<dd>Examples using the <code>task_arena</code> feature.
<dt><a href="test_all/index.html">test_all</a>
<dd>Examples that test various components of Intel TBB.
<dt><a href="common/index.html">common</a>
<dd>Common files for building various examples. Should not be used directly. But if you copy an example to other place this folder should be copied also and should have the same relative path for copied example.
</dl>
</div>
</div>
<div class="changes">
<div class="h3-alike">Build Instructions</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<br>
<div class="note">
Note: Some of the following directions refer to a shell window. This refers
to the command prompt environment/window normally used on your system:
<ul>
<li>cmd.exe command prompt window for Windows* systems
<li>sh, bash, csh, ksh, etc. (or compatible) shell window for Windows*, Linux* or macOS* systems
</ul>
</div>
<p>
Set up the environment for using Intel TBB:
</p>
<div class="h4-alike">To set up the environment for Windows* OS:</div>
<input type="checkbox">
<div class="show-hide">
<p>
It is <b>strongly</b> recommended to set up the environment when installing Intel TBB.
Do this by selecting the appropriate check-box during the install. However, if the environment is not set up
during installation, or you wish to build for an alternate architecture or Microsoft* Visual Studio* version,
it may be set up, for a given type of shell window, by using one of the following commands:
</p>
<dl>
<dt>For cmd.exe (command prompt):
<dd>
<pre>
&lt;<i>installdir</i>&gt;/bin/tbbvars.bat (arch) [vs]
</pre>
<dt>where:
<dd>
<li><i>(arch)</i> argument represents target architecture. Its possible values are 'ia32' or 'intel64'.
<li><i>[vs]</i> argument represents target version of Microsoft* Visual Studio*. Its possible values are:
<ul class='circ'>
<li><i>'vs&lt;msvs_version&gt;'</i> - to use Intel TBB library with Microsoft* Visual Studio* <i>&lt;msvs_version&gt;</i> runtime DLLs, e.g.: <code>tbbvars&nbsp;intel64&nbsp;vs2015</code>
<br><i>Note:</i> for the most up to date supported versions of Microsoft* Visual Studio*, see the <a href="http://software.intel.com/en-us/articles/intel-threading-building-blocks-release-notes">release notes.</a>
<li><i>'all'</i> - to use Intel TBB binaries statically linked with Microsoft Visual C++ runtime.
<br>If <i>[vs]</i> is not set the <i>'all'</i> value will be used by default.
</ul>
</dl>
</div>
<br>
<div class="h4-alike">To set up the environment for Linux* OS and macOS*:</div>
<input type="checkbox">
<div class="show-hide">
<p>
The environment may be set up, for a given type of shell window, by using one of the following commands:
</p>
<dl>
<dt>For sh, bash, ksh, dash (or compatibles):
<dd>
<pre>
<b>.</b> &lt;<i>installdir</i>&gt;/bin/tbbvars.sh (arch) [platform [TBBROOT_detection_mode]]
</pre>
<dt>For csh (or compatibles):
<dd>
<pre>
source &lt;<i>installdir</i>&gt;/bin/tbbvars.csh (arch) [platform [TBBROOT_detection_mode]]
</pre>
<dt>where:
<dd>
<li><i>(arch)</i> argument represents target architecture. Its possible values are <i>'ia32'</i> or <i>'intel64'</i>.
<li><i>[platform]</i> argument represents target platform. Its possible values are <i>'linux'</i> or <i>'android'</i>.
<li><i>[TBBROOT_detection_mode]</i> argument represents TBBROOT path detection method. Its only possible value is <i>'auto_tbbroot'</i>. In this case the environment variable TBBROOT is detected automatically by using the tbbvars script directory path.
</dl>
Environment setup need only be performed once per shell window to be used.
<br>Always source tbbvars.sh or tbbvars.csh rather than executing them directly.
<br>If the arguments to the sourced script are ignored (consult documentation for your shell) the alternative way to specify target is environment variables COMPILERVARS_ARCHITECTURE to pass (arch) to the script and COMPILERVARS_PLATFORM to pass [platform].
</div>
<p>
Build each example by using one of the following methods:
</p>
<div class="h4-alike">To build by using a Microsoft* Visual Studio* project (Windows* systems):</div>
<input type="checkbox">
<div class="show-hide">
<ol>
<li>Identify the solution (*.sln) file for the example you wish to build and run. The *.sln file for each example is in the example's <i>msvs</i> sub-directory.
<li>Open the project by using one of the following methods:
<ul class="disc">
<li>Navigate to the *.sln file from My Computer, by using Windows Explorer, or by using another file browser. Double-click the *.sln file to invoke Microsoft* Visual Studio* and open the project.</li>
<li>Invoke Microsoft* Visual Studio* from the Start menu and use the "Open Project" dialog to navigate to and open the project.</li>
</ul>
</li>
<li>Press &lt;ctrl-F5&gt; to build and run the example.</li>
<li>If you copied an example to another place separately from libraries you need to
set %TBBROOT% variable pointing to &lt;installdir&gt; folder.</li>
</ol>
</div>
<br>
<div class="h4-alike">To build by using a Xcode* IDE project (macOS* systems):</div>
<input type="checkbox">
<div class="show-hide">
<br>
<div class="note">
Note: Xcode* project instructions are not applicable for the Intel TBB Sample Bundle for Intel&reg; System Studio
because Intel System Studio does not support macOS*. For additional information, see the
<a href="https://software.intel.com/en-us/articles/intel-system-studio-release-notes">Release Notes</a>.
</div>
<ol>
<li>Identify the project (*.xcodeproj) file for the example you wish to build and run. The *.xcodeproj file is in the example's <i>xcode</i> sub-directory.</li>
<li>Open the project by using one of the following methods:
<ul class="disc">
<li>Navigate to the *.xcodeproj file by using the Finder.Double-click the *.xcodeproj file to invoke the Xcode* IDE and open the project.</li>
<li>Invoke the Xcode* IDE and use the "File -> Open" dialog to navigate to and open the project.</li>
</ul>
</li>
<li>Press &lt;Apple-R&gt;, or press the "Build and Go" button in the toolbox, to build and run the example.
</li>
</ol>
</div>
<br>
<div class="h4-alike">To build by using a Makefile (Windows*, Linux* or macOS* systems):</div>
<input type="checkbox">
<div class="show-hide">
<ol>
<li>Open a shell window
<ul class="disc">
<li>For Windows* systems, make sure this shell window has the proper environment
defined for use with Microsoft* Visual Studio*. Such shell can be invoked from the Start menu, under Microsoft* Visual Studio*, Microsoft* Visual Studio Tools*, Microsoft* Visual Studio* Command Prompt.</li>
</ul>
<li>Set up the environment in this shell window for use with Intel TBB.
<br>See above for how to set up the environment for Windows*, Linux* or macOS* systems.
<li>Unless you installed Intel TBB yourself, you may not have write permissions to the directory
containing the example. In this case, make a copy of the example, and use the copy for the following steps.
<li>In the shell window, navigate to the directory for the example
(or to the directory for the copy of the example if you made one in the previous step).
<li>Use one or more of the following commands to build and run the example.
Here, make refers to the make command normally used on your system: this could be
nmake, gmake, or make on Windows* systems, or make or gmake on Linux* or macOS* systems.
<dl>
<dt><tt>make</tt>
<dd>Default build and run. Equivalent to 'make release test'.
<dt><tt>make release</tt>
<dd>Compile and link against the release version of Intel TBB runtime library. The resulting executable is left in the directory for the example.
<dt><tt>make debug</tt>
<dd>Compile and link against the debug version of Intel TBB runtime library. The resulting executable is left in the directory for the example.
<dt><tt>make profile</tt>
<dd>Similar to 'make release' but also enables additional support for Intel&reg; Parallel Studio XE analysis tools.
<br>
<div class="note">
Note: Only flow graph examples are currently supported.
</div>
<dt><tt>make test</tt>
<dd>Run an executable previously produced by one of the above commands.
<dt><tt>make <b>[</b>(above options or targets)<b>]</b> CXX=<b>{</b>icl, icc<b>}</b></tt>
<dd>Build and run as above, but use Intel&reg; C++ Compiler instead of default, native compilers (e.g., icl instead of cl.exe on Windows* systems, or icc instead of g++ on Linux* or macOS* systems).
<dt><tt>make <b>[</b>(above options or targets)<b>]</b> offload=mic</tt>
<dd>Build and run the offload version of an example for Intel&reg; Many Integrated Core (Intel&reg; MIC) Architecture.
<br>
<div class="note">
Note: Only Intel&reg; MIC Architecture with Linux* based host is currently supported.
</div>
<dt><tt>make clean</tt>
<dd>Remove any executables or intermediate files produced by the above commands.
</dl>
</ol>
</div>
<br>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a> (available only in the Intel&reg; Parallel Studio and Intel&reg; System Studio Online Samples packages and the open-source version of Intel TBB)
<hr>
<div class="changes">
<div class="h3-alike">Legal Information:</div>
<input type="checkbox">
<div class="show-hide">
<br>
<div class="tablenoborder">
<table border="1" rules="all" frame="border" cellspacing="0" cellpadding="4" summary="">
<thead align="left">
<tr>
<th width="100%" align="left" class="cellrowborder" valign="top">
<p>Optimization Notice</p>
</th>
</tr>
</thead>
<tbody>
<tr>
<td width="100%" class="bgcolor(#f5f5f5)" valign="top" bgcolor="#f5f5f5">
<p>Intel's compilers may or may not optimize to the same
degree for non-Intel microprocessors for optimizations that
are not unique to Intel microprocessors. These optimizations
include SSE2, SSE3, and SSSE3 instruction sets and other
optimizations. Intel does not guarantee the availability,
functionality, or effectiveness of any optimization on
microprocessors not manufactured by Intel.
Microprocessor-dependent optimizations in this product are
intended for use with Intel microprocessors. Certain
optimizations not specific to Intel microarchitecture are
reserved for Intel microprocessors. Please refer to the
applicable product User and Reference Guides for more
information regarding the specific instruction sets covered by
this notice.
</p>
<p>Notice revision #20110804
</p>
</td>
</tr>
</tbody>
</table>
</div>
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,344 @@
<!DOCTYPE html>
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<meta charset="UTF-8">
<style>
::selection {
background: #b7ffb7;
}
::-moz-selection {
background: #b7ffb7;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
width: 800px;
margin: 0 auto;
}
#banner {
/* Div for banner */
float:left;
margin: 0px;
margin-bottom: 10px;
width: 100%;
background-color: #0071C5;
z-index: 0;
}
#banner .logo {
/* Apply to logo in banner. Add as class to image tag. */
float: left;
margin-right: 20px;
margin-left: 20px;
margin-top: 15px;
padding-bottom: 5px;
}
h1 {
text-align: center;
font-size: 36px;
}
h1.title {
/* Add as class to H1 in banner */
font-family: "Intel Clear", Verdana, Arial, sans-serif;
font-weight:normal;
color: #FFFFFF;
font-size: 170%;
margin-right: 40px;
margin-left: 40px;
padding-right: 20px;
text-indent: 20px;
}
.h3-alike {
display:inline;
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
h3 {
font-size: 1.17em;
font-weight: bold;
color: #0071C5;
}
.h4-alike {
display:inline;
font-size: 1.05em;
font-weight: bold;
}
pre {
font-family: "Consolas", Monaco, monospace;
font-size:small;
background: #fafafa;
margin: 0;
padding-left:20px;
}
#footer {
font-size: small;
}
code {
font-family: "Consolas", Monaco, monospace;
}
.code-block
{
padding-left:20px;
}
.changes {
margin: 1em 0;
}
.changes input:active {
position: relative;
top: 1px;
}
.changes input:hover:after {
padding-left: 16px;
font-size: 10px;
content: 'More';
}
.changes input:checked:hover:after {
content: 'Less';
}
.changes input + .show-hide {
display: none;
}
.changes input:checked + .show-hide {
display: block;
}
ul {
margin: 0;
padding: 0.5em 0 0.5em 2.5em;
}
ul li {
margin-bottom: 3px;
}
ul li:last-child {
margin-bottom: 0;
}
.disc {
list-style-type:disc
}
.circ {
list-style-type:circle
}
.single {
padding: 0 0.5em;
}
/* ------------------------------------------------- */
/* Table styles */
table{
margin-bottom:5pt;
border-collapse:collapse;
margin-left:0px;
margin-top:0.3em;
font-size:10pt;
}
tr{
vertical-align:top;
}
th,
th h3{
padding:4px;
text-align:left;
background-color:#0071C5;
font-weight:bold;
margin-top:1px;
margin-bottom:0;
color:#FFFFFF;
font-size:10pt;
vertical-align:middle;
}
th{
border:1px #dddddd solid;
padding-top:2px;
padding-bottom:0px;
padding-right:3px;
padding-left:3px;
}
td{
border:1px #dddddd solid;
vertical-align:top;
font-size:100%;
text-align:left;
margin-bottom:0;
}
td,
td p{
margin-top:0;
margin-left:0;
text-align:left;
font-size:inherit;
line-height:120%;
}
td p{
margin-bottom:0;
padding-top:5px;
padding-bottom:5px;
padding-right:5px;
padding-left:1px;
}
.noborder{
border:0px none;
}
.noborder1stcol{
border:0px none;
padding-left:0pt;
}
td ol{
font-size:inherit;
margin-left:28px;
}
td ul{
font-size:inherit;
margin-left:24px;
}
.DefListTbl{
width:90%;
margin-left:-3pt;
}
.syntaxdiagramtbl{
margin-left:-3pt;
}
.sdtbl{
}
.sdrow{
}
.sdtblp{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.idepara, .ide_para{
border:0px none;
font-size:inherit;
line-height:120%;
margin-bottom:0;
padding-bottom:0px;
padding-top:5px;
padding-left:0px;
padding-right:5px;
vertical-align:top;
}
.specs {
border-collapse:collapse;
}
.specs td, .specs th {
font-size: 14px;
}
.specs td {
border: 1px solid black;
}
.specs td td, .specs td th {
border: none;
}
.specs td, .specs td td, .specs td th {
padding: 0 0.2em 0.2em;
text-align: center;
}
.specs td tr:last-child td,
.specs td tr:last-child th {
padding: 0 0.2em;
}
.serial-time {
}
.modified-time {
width: 6.5em;
}
.compiler {
}
.comp-opt {
}
.sys-specs {
width: 18em;
}
.note {
font-size:small;
font-style: italic;
}
</style>
<title>Intel&reg; Threading Building Blocks. Samples on parallel_do algorithm</title>
</head>
<body>
<div id="banner">
<img class="logo" src="data:image/png;base64,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
9Or1LzUmVVz+HJXDAAAAAElFTkSuQmCC">
<h1 class="title">Intel&reg; Threading Building Blocks.<br>Samples on <code>parallel_do</code> algorithm</h1>
</div>
<p>
This directory has examples of the <code>parallel_do</code> algorithm.
</p>
<div class="changes">
<div class="h3-alike">Directories</div>
<input type="checkbox" checked="checked">
<div class="show-hide">
<dl>
<dt><a href="parallel_preorder/readme.html">parallel_preorder</a>
<dd>Parallel preorder traversal of a graph.
</dl>
</div>
</div>
<br>
<a href="../index.html">Up to parent directory</a>
<hr>
<div class="changes">
<div class="h3-alike">Legal Information:</div>
<input type="checkbox">
<div class="show-hide">
<p>
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
<br>* Other names and brands may be claimed as the property of others.
<br>&copy; 2020, Intel Corporation
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,108 @@
/*
Copyright (c) 2005-2020 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 <cstdlib>
#include "Graph.h"
#include <iostream>
using namespace std;
Cell::Cell(const Cell& other)
: op( other.op )
, value( other.value )
, successor( other.successor )
{
ref_count = other.ref_count.load();
input[0] = other.input[0];
input[1] = other.input[1];
}
void Graph::create_random_dag( size_t number_of_nodes ) {
my_vertex_set.resize(number_of_nodes);
for( size_t k=0; k<number_of_nodes; ++k ) {
Cell& c = my_vertex_set[k];
int op = int((rand()>>8)%5u);
if( op>int(k) ) op = int(k);
switch( op ) {
default:
c.op = OP_VALUE;
c.value = Cell::value_type((float)k);
break;
case 1:
c.op = OP_NEGATE;
break;
case 2:
c.op = OP_SUB;
break;
case 3:
c.op = OP_ADD;
break;
case 4:
c.op = OP_MUL;
break;
}
for( int j=0; j<ArityOfOp[c.op]; ++j ) {
Cell& input = my_vertex_set[rand()%k];
c.input[j] = &input;
}
}
}
void Graph::print() {
for( size_t k=0; k<my_vertex_set.size(); ++k ) {
std::cout<<"Cell "<<k<<":";
for( size_t j=0; j<my_vertex_set[k].successor.size(); ++j )
std::cout<<" "<<int(my_vertex_set[k].successor[j] - &my_vertex_set[0]);
std::cout<<std::endl;
}
}
void Graph::get_root_set( vector<Cell*>& root_set ) {
for( size_t k=0; k<my_vertex_set.size(); ++k ) {
my_vertex_set[k].successor.clear();
}
root_set.clear();
for( size_t k=0; k<my_vertex_set.size(); ++k ) {
Cell& c = my_vertex_set[k];
c.ref_count = ArityOfOp[c.op];
for( int j=0; j<ArityOfOp[c.op]; ++j ) {
c.input[j]->successor.push_back(&c);
}
if( ArityOfOp[c.op]==0 )
root_set.push_back(&my_vertex_set[k]);
}
}
void Cell::update() {
switch( op ) {
case OP_VALUE:
break;
case OP_NEGATE:
value = -(input[0]->value);
break;
case OP_ADD:
value = input[0]->value + input[1]->value;
break;
case OP_SUB:
value = input[0]->value - input[1]->value;
break;
case OP_MUL:
value = input[0]->value * input[1]->value;
break;
}
}

Some files were not shown because too many files have changed in this diff Show More