This repository has been archived by the owner on Mar 21, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 756
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ability to place Thrust in a custom namespace.
This provides a workaround for downstream projects that encounter a variety of issues from dynamically linking multiple libraries that use Thrust. See the new `thrust/detail/config/namespace.h` header for details. Added several tests and checks to validate that this behavior is correct, and the `__THRUST_DEFINE_HAS_MEMBER_FUNCTION` utility has been rewritten to WAR an nvcc bug when the old implementation was used with objects in an anonymous namespace. New tests: - testing/namespace_anonymous.cu - testing/namespace_wrapped.cu - testing/cmake/check_namespace.cmake
- Loading branch information
1 parent
07ec655
commit d7d55c4
Showing
623 changed files
with
1,747 additions
and
2,230 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# Check all files in thrust to make sure that they use | ||
# THRUST_NAMESPACE_BEGIN/END instead of bare `namespace thrust {}` declarations. | ||
# | ||
# This is run as a ctest test named `thrust.test.cmake.check_namespace`, or | ||
# manually with: | ||
# cmake -D "Thrust_SOURCE_DIR=<thrust project root>" -P check_namespace.cmake | ||
|
||
cmake_minimum_required(VERSION 3.15) | ||
|
||
set(exclusions | ||
# This defines the macros and must have bare namespace declarations: | ||
thrust/detail/config/namespace.h | ||
) | ||
|
||
function(count_substrings input search_regex output_var) | ||
string(REGEX MATCHALL "${search_regex}" matches "${input}") | ||
list(LENGTH matches num_matches) | ||
set(${output_var} ${num_matches} PARENT_SCOPE) | ||
endfunction() | ||
|
||
set(bare_ns_regex "namespace[ \n\r\t]+thrust[ \n\r\t]*\\{") | ||
|
||
# Validation check for the above regex: | ||
count_substrings([=[ | ||
namespace thrust{ | ||
namespace thrust { | ||
namespace thrust { | ||
namespace thrust { | ||
namespace thrust | ||
{ | ||
namespace | ||
thrust | ||
{ | ||
]=] | ||
${bare_ns_regex} valid_count) | ||
if (NOT valid_count EQUAL 6) | ||
message(FATAL_ERROR "Validation of bare namespace regex failed: " | ||
"Matched ${valid_count} times, expected 6.") | ||
endif() | ||
|
||
set(exit_code 0) | ||
file(GLOB_RECURSE thrust_srcs | ||
RELATIVE "${Thrust_SOURCE_DIR}" | ||
"${Thrust_SOURCE_DIR}/thrust/*.h" | ||
"${Thrust_SOURCE_DIR}/thrust/*.inl" | ||
"${Thrust_SOURCE_DIR}/testing/*.cu" | ||
"${Thrust_SOURCE_DIR}/examples/*.cu" | ||
) | ||
|
||
foreach(src ${thrust_srcs}) | ||
if (${src} IN_LIST exclusions) | ||
continue() | ||
endif() | ||
|
||
file(READ "${Thrust_SOURCE_DIR}/${src}" src_contents) | ||
|
||
count_substrings("${src_contents}" "${bare_ns_regex}" bare_ns_count) | ||
count_substrings("${src_contents}" THRUST_NAMESPACE_BEGIN begin_count) | ||
count_substrings("${src_contents}" THRUST_NAMESPACE_END end_count) | ||
|
||
if (NOT bare_ns_count EQUAL 0) | ||
message("'${src}' contains 'namespace thrust {...}'. Replace with THRUST_NAMESPACE macros.") | ||
set(exit_code 1) | ||
endif() | ||
|
||
if (NOT begin_count EQUAL end_count) | ||
message("'${src}' namespace macros are unbalanced:") | ||
message(" - THRUST_NAMESPACE_BEGIN occurs ${begin_count} times.") | ||
message(" - THRUST_NAMESPACE_END occurs ${end_count} times.") | ||
set(exit_code 1) | ||
endif() | ||
endforeach() | ||
|
||
if (NOT exit_code EQUAL 0) | ||
message(FATAL_ERROR "Errors detected.") | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Put all of Thrust and CUB inside an anonymous namespace. | ||
#define THRUST_CUB_USE_ANON_NAMESPACE | ||
|
||
#include <thrust/device_vector.h> | ||
#include <thrust/host_vector.h> | ||
#include <thrust/iterator/constant_iterator.h> | ||
#include <thrust/iterator/counting_iterator.h> | ||
#include <thrust/transform.h> | ||
|
||
#include <unittest/unittest.h> | ||
|
||
// Test that we can use a few common utilities and algorithms from an anon | ||
// namespace at runtime. More extensive testing is performed by the header | ||
// tests and the check_namespace.cmake test. | ||
void TestAnonymousNamespace() | ||
{ | ||
const std::size_t n = 2048; | ||
const auto in_1_begin = thrust::make_constant_iterator<int>(12); | ||
const auto in_2_begin = thrust::make_counting_iterator<int>(1024); | ||
// Check that the qualifier resolves properly: | ||
THRUST_NS_QUALIFIER::device_vector<int> d_out(n); | ||
|
||
thrust::transform(in_1_begin, in_1_begin + n, | ||
in_2_begin, | ||
d_out.begin(), | ||
thrust::plus<>{}); | ||
|
||
thrust::host_vector<int> h_out(d_out); | ||
|
||
for (std::size_t i = 0; i < n; ++i) | ||
{ | ||
ASSERT_EQUAL(h_out[i], static_cast<int>(i) + 1024 + 12); | ||
} | ||
} | ||
DECLARE_UNITTEST(TestAnonymousNamespace); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Put all of Thrust and CUB inside a `wrap::` namespace. | ||
#define THRUST_CUB_WRAPPED_NAMESPACE wrap | ||
|
||
#include <thrust/device_vector.h> | ||
#include <thrust/host_vector.h> | ||
#include <thrust/iterator/constant_iterator.h> | ||
#include <thrust/iterator/counting_iterator.h> | ||
#include <thrust/transform.h> | ||
|
||
#include <unittest/unittest.h> | ||
|
||
// Test that we can use a few common utilities and algorithms from a wrapped | ||
// namespace at runtime. More extensive testing is performed by the header | ||
// tests and the check_namespace.cmake test. | ||
void TestWrappedNamespace() | ||
{ | ||
const std::size_t n = 2048; | ||
const auto in_1_begin = ::wrap::thrust::make_constant_iterator<int>(12); | ||
const auto in_2_begin = ::wrap::thrust::make_counting_iterator<int>(1024); | ||
// Check that the qualifier resolves properly: | ||
THRUST_NS_QUALIFIER::device_vector<int> d_out(n); | ||
|
||
::wrap::thrust::transform(in_1_begin, | ||
in_1_begin + n, | ||
in_2_begin, | ||
d_out.begin(), | ||
::wrap::thrust::plus<>{}); | ||
|
||
::wrap::thrust::host_vector<int> h_out(d_out); | ||
|
||
for (std::size_t i = 0; i < n; ++i) | ||
{ | ||
ASSERT_EQUAL(h_out[i], static_cast<int>(i) + 1024 + 12); | ||
} | ||
} | ||
DECLARE_UNITTEST(TestWrappedNamespace); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.