Skip to content

Commit 3621177

Browse files
committed
Fall back to building TBB from local source code
1 parent 73b076e commit 3621177

File tree

488 files changed

+150181
-5
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

488 files changed

+150181
-5
lines changed

R/build.R

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,18 @@ tbbCxxFlags <- function() {
5353

5454
# Return the linker flags requried for TBB on this platform
5555
tbbLdFlags <- function() {
56-
tbb <- tbbLibPath()
57-
paste("-L", asBuildPath(dirname(tbb)), " -ltbb -ltbbmalloc", sep = "")
56+
tbb_path <- normalizePath(Sys.getenv("TBB_LIBRARY_FILE"))
57+
if (file.exists(tbb_path)) {
58+
paste("-L", asBuildPath(dirname(tbb)), " -ltbb -ltbbmalloc", sep = "")
59+
} else {
60+
# on Windows and Solaris we need to explicitly link against tbb.dll
61+
if ((Sys.info()['sysname'] %in% c("Windows", "SunOS")) && !isSparc()) {
62+
tbb <- tbbLibPath()
63+
paste("-L", asBuildPath(dirname(tbb)), " -ltbb -ltbbmalloc", sep = "")
64+
} else {
65+
""
66+
}
67+
}
5868
}
5969

6070
# Determine the platform-specific path to the TBB library
@@ -67,7 +77,20 @@ tbbLibPath <- function(suffix = "") {
6777
"SunOS" = paste("libtbb", suffix, ".so", sep = "")
6878
)
6979

70-
normalizePath(Sys.getenv("TBB_LIBRARY_FILE"))
80+
tbb_path <- normalizePath(Sys.getenv("TBB_LIBRARY_FILE"))
81+
if (file.exists(tbb_path)) {
82+
tbb_path
83+
} else {
84+
if ((sysname %in% names(tbbSupported)) && !isSparc()) {
85+
libDir <- "lib/"
86+
if (sysname == "Windows")
87+
libDir <- paste(libDir, .Platform$r_arch, "/", sep="")
88+
system.file(paste(libDir, tbbSupported[[sysname]], sep = ""),
89+
package = "RcppParallel")
90+
} else {
91+
NULL
92+
}
93+
}
7194
}
7295

7396
isSparc <- function() {
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
/*
2+
Copyright (c) 2005-2018 Intel Corporation
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
16+
17+
18+
19+
*/
20+
21+
#ifndef __TBB_SERIAL_parallel_for_H
22+
#define __TBB_SERIAL_parallel_for_H
23+
24+
#include "tbb_annotate.h"
25+
26+
#ifndef __TBB_NORMAL_EXECUTION
27+
#include "tbb/blocked_range.h"
28+
#include "tbb/partitioner.h"
29+
#endif
30+
31+
#if TBB_USE_EXCEPTIONS
32+
#include <stdexcept>
33+
#include <string> // required to construct std exception classes
34+
#else
35+
#include <cstdlib>
36+
#include <iostream>
37+
#endif
38+
39+
namespace tbb {
40+
namespace serial {
41+
namespace interface9 {
42+
43+
// parallel_for serial annotated implementation
44+
45+
template< typename Range, typename Body, typename Partitioner >
46+
class start_for : tbb::internal::no_copy {
47+
Range my_range;
48+
const Body my_body;
49+
typename Partitioner::task_partition_type my_partition;
50+
void execute();
51+
52+
//! Constructor for root task.
53+
start_for( const Range& range, const Body& body, Partitioner& partitioner ) :
54+
my_range( range ),
55+
my_body( body ),
56+
my_partition( partitioner )
57+
{
58+
}
59+
60+
//! Splitting constructor used to generate children.
61+
/** this becomes left child. Newly constructed object is right child. */
62+
start_for( start_for& parent_, typename Partitioner::split_type& split_obj ) :
63+
my_range( parent_.my_range, split_obj ),
64+
my_body( parent_.my_body ),
65+
my_partition( parent_.my_partition, split_obj )
66+
{
67+
}
68+
69+
public:
70+
static void run( const Range& range, const Body& body, Partitioner& partitioner ) {
71+
if( !range.empty() ) {
72+
ANNOTATE_SITE_BEGIN( tbb_parallel_for );
73+
{
74+
start_for a( range, body, partitioner );
75+
a.execute();
76+
}
77+
ANNOTATE_SITE_END( tbb_parallel_for );
78+
}
79+
}
80+
};
81+
82+
template< typename Range, typename Body, typename Partitioner >
83+
void start_for< Range, Body, Partitioner >::execute() {
84+
if( !my_range.is_divisible() || !my_partition.is_divisible() ) {
85+
ANNOTATE_TASK_BEGIN( tbb_parallel_for_range );
86+
{
87+
my_body( my_range );
88+
}
89+
ANNOTATE_TASK_END( tbb_parallel_for_range );
90+
} else {
91+
typename Partitioner::split_type split_obj;
92+
start_for b( *this, split_obj );
93+
this->execute(); // Execute the left interval first to keep the serial order.
94+
b.execute(); // Execute the right interval then.
95+
}
96+
}
97+
98+
//! Parallel iteration over range with default partitioner.
99+
/** @ingroup algorithms **/
100+
template<typename Range, typename Body>
101+
void parallel_for( const Range& range, const Body& body ) {
102+
serial::interface9::start_for<Range,Body,const __TBB_DEFAULT_PARTITIONER>::run(range,body,__TBB_DEFAULT_PARTITIONER());
103+
}
104+
105+
//! Parallel iteration over range with simple partitioner.
106+
/** @ingroup algorithms **/
107+
template<typename Range, typename Body>
108+
void parallel_for( const Range& range, const Body& body, const simple_partitioner& partitioner ) {
109+
serial::interface9::start_for<Range,Body,const simple_partitioner>::run(range,body,partitioner);
110+
}
111+
112+
//! Parallel iteration over range with auto_partitioner.
113+
/** @ingroup algorithms **/
114+
template<typename Range, typename Body>
115+
void parallel_for( const Range& range, const Body& body, const auto_partitioner& partitioner ) {
116+
serial::interface9::start_for<Range,Body,const auto_partitioner>::run(range,body,partitioner);
117+
}
118+
119+
//! Parallel iteration over range with static_partitioner.
120+
/** @ingroup algorithms **/
121+
template<typename Range, typename Body>
122+
void parallel_for( const Range& range, const Body& body, const static_partitioner& partitioner ) {
123+
serial::interface9::start_for<Range,Body,const static_partitioner>::run(range,body,partitioner);
124+
}
125+
126+
//! Parallel iteration over range with affinity_partitioner.
127+
/** @ingroup algorithms **/
128+
template<typename Range, typename Body>
129+
void parallel_for( const Range& range, const Body& body, affinity_partitioner& partitioner ) {
130+
serial::interface9::start_for<Range,Body,affinity_partitioner>::run(range,body,partitioner);
131+
}
132+
133+
//! Implementation of parallel iteration over stepped range of integers with explicit step and partitioner (ignored)
134+
template <typename Index, typename Function, typename Partitioner>
135+
void parallel_for_impl(Index first, Index last, Index step, const Function& f, Partitioner& ) {
136+
if (step <= 0 ) {
137+
#if TBB_USE_EXCEPTIONS
138+
throw std::invalid_argument( "nonpositive_step" );
139+
#else
140+
std::cerr << "nonpositive step in a call to parallel_for" << std::endl;
141+
std::abort();
142+
#endif
143+
} else if (last > first) {
144+
// Above "else" avoids "potential divide by zero" warning on some platforms
145+
ANNOTATE_SITE_BEGIN( tbb_parallel_for );
146+
for( Index i = first; i < last; i = i + step ) {
147+
ANNOTATE_TASK_BEGIN( tbb_parallel_for_iteration );
148+
{ f( i ); }
149+
ANNOTATE_TASK_END( tbb_parallel_for_iteration );
150+
}
151+
ANNOTATE_SITE_END( tbb_parallel_for );
152+
}
153+
}
154+
155+
//! Parallel iteration over a range of integers with explicit step and default partitioner
156+
template <typename Index, typename Function>
157+
void parallel_for(Index first, Index last, Index step, const Function& f) {
158+
parallel_for_impl<Index,Function,const auto_partitioner>(first, last, step, f, auto_partitioner());
159+
}
160+
//! Parallel iteration over a range of integers with explicit step and simple partitioner
161+
template <typename Index, typename Function>
162+
void parallel_for(Index first, Index last, Index step, const Function& f, const simple_partitioner& p) {
163+
parallel_for_impl<Index,Function,const simple_partitioner>(first, last, step, f, p);
164+
}
165+
//! Parallel iteration over a range of integers with explicit step and auto partitioner
166+
template <typename Index, typename Function>
167+
void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& p) {
168+
parallel_for_impl<Index,Function,const auto_partitioner>(first, last, step, f, p);
169+
}
170+
//! Parallel iteration over a range of integers with explicit step and static partitioner
171+
template <typename Index, typename Function>
172+
void parallel_for(Index first, Index last, Index step, const Function& f, const static_partitioner& p) {
173+
parallel_for_impl<Index,Function,const static_partitioner>(first, last, step, f, p);
174+
}
175+
//! Parallel iteration over a range of integers with explicit step and affinity partitioner
176+
template <typename Index, typename Function>
177+
void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& p) {
178+
parallel_for_impl(first, last, step, f, p);
179+
}
180+
181+
//! Parallel iteration over a range of integers with default step and default partitioner
182+
template <typename Index, typename Function>
183+
void parallel_for(Index first, Index last, const Function& f) {
184+
parallel_for_impl<Index,Function,const auto_partitioner>(first, last, static_cast<Index>(1), f, auto_partitioner());
185+
}
186+
//! Parallel iteration over a range of integers with default step and simple partitioner
187+
template <typename Index, typename Function>
188+
void parallel_for(Index first, Index last, const Function& f, const simple_partitioner& p) {
189+
parallel_for_impl<Index,Function,const simple_partitioner>(first, last, static_cast<Index>(1), f, p);
190+
}
191+
//! Parallel iteration over a range of integers with default step and auto partitioner
192+
template <typename Index, typename Function>
193+
void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& p) {
194+
parallel_for_impl<Index,Function,const auto_partitioner>(first, last, static_cast<Index>(1), f, p);
195+
}
196+
//! Parallel iteration over a range of integers with default step and static partitioner
197+
template <typename Index, typename Function>
198+
void parallel_for(Index first, Index last, const Function& f, const static_partitioner& p) {
199+
parallel_for_impl<Index,Function,const static_partitioner>(first, last, static_cast<Index>(1), f, p);
200+
}
201+
//! Parallel iteration over a range of integers with default step and affinity_partitioner
202+
template <typename Index, typename Function>
203+
void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& p) {
204+
parallel_for_impl(first, last, static_cast<Index>(1), f, p);
205+
}
206+
207+
} // namespace interfaceX
208+
209+
using interface9::parallel_for;
210+
211+
} // namespace serial
212+
213+
#ifndef __TBB_NORMAL_EXECUTION
214+
using serial::interface9::parallel_for;
215+
#endif
216+
217+
} // namespace tbb
218+
219+
#endif /* __TBB_SERIAL_parallel_for_H */
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
Copyright (c) 2005-2018 Intel Corporation
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
16+
17+
18+
19+
*/
20+
21+
#ifndef __TBB_annotate_H
22+
#define __TBB_annotate_H
23+
24+
// Macros used by the Intel(R) Parallel Advisor.
25+
#ifdef __TBB_NORMAL_EXECUTION
26+
#define ANNOTATE_SITE_BEGIN( site )
27+
#define ANNOTATE_SITE_END( site )
28+
#define ANNOTATE_TASK_BEGIN( task )
29+
#define ANNOTATE_TASK_END( task )
30+
#define ANNOTATE_LOCK_ACQUIRE( lock )
31+
#define ANNOTATE_LOCK_RELEASE( lock )
32+
#else
33+
#include <advisor-annotate.h>
34+
#endif
35+
36+
#endif /* __TBB_annotate_H */

0 commit comments

Comments
 (0)