Skip to content

Commit 53bfe25

Browse files
committed
forced symbol, compiling with Intel OK in Rocky
1 parent 323b5f0 commit 53bfe25

23 files changed

+334
-156
lines changed

CMakeLists.txt

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ if(MSVC)
2626
endif()
2727
else()
2828
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
29-
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto=auto")
29+
3030
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
3131
add_compile_options(
3232
-Wall -Wextra -Wpedantic -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align
@@ -39,6 +39,13 @@ else()
3939
-Wformat-overflow -Wformat-truncation
4040
)
4141
endif()
42+
43+
if (CMAKE_CXX_COMPILER_ID MATCHES "Intel")
44+
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION OFF)
45+
else()
46+
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto=auto")
47+
endif()
48+
4249
endif()
4350

4451
if (APPLE)
@@ -269,13 +276,41 @@ install(FILES README.md LICENSE DESTINATION ${SKBUILD_PROJECT_NAME})
269276
install(DIRECTORY src/python/noder/ DESTINATION ${SKBUILD_PROJECT_NAME} FILES_MATCHING PATTERN "*.py*")
270277
install(DIRECTORY include DESTINATION ${SKBUILD_PROJECT_NAME})
271278

279+
# option(ENABLE_TESTS "Enable test compilation" ON)
280+
# if(ENABLE_TESTS)
281+
# file(GLOB_RECURSE TEST_FILES "tests/*.cpp" "tests/*.hpp")
282+
# pybind11_add_module(tests MODULE ${TEST_FILES})
283+
# target_link_libraries(tests PRIVATE core_shared)
284+
# target_include_directories(tests PRIVATE ${CMAKE_INSTALL_INCLUDEDIR} ${CMAKE_SOURCE_DIR}/tests)
285+
# add_dependencies(tests core_shared)
286+
# if(APPLE)
287+
# target_link_options(tests PRIVATE "-Wl,-force_load,$<TARGET_FILE:core_shared>")
288+
# endif()
289+
290+
# install(TARGETS tests DESTINATION ${SKBUILD_PROJECT_NAME})
291+
# install(DIRECTORY tests DESTINATION ${SKBUILD_PROJECT_NAME})
292+
# endif()
293+
294+
272295
option(ENABLE_TESTS "Enable test compilation" ON)
273296
if(ENABLE_TESTS)
274-
file(GLOB_RECURSE TEST_FILES "tests/*.cpp" "tests/*.hpp")
275-
pybind11_add_module(tests MODULE ${TEST_FILES})
297+
file(GLOB_RECURSE TEST_CPP CONFIGURE_DEPENDS
298+
"${CMAKE_SOURCE_DIR}/tests/*.cpp")
299+
300+
pybind11_add_module(tests MODULE ${TEST_CPP})
301+
# tests module binds functions implemented across many translation units;
302+
# keep default visibility so symbols are resolvable at import time.
303+
set_target_properties(tests PROPERTIES
304+
CXX_VISIBILITY_PRESET default
305+
VISIBILITY_INLINES_HIDDEN OFF
306+
)
276307
target_link_libraries(tests PRIVATE core_shared)
277-
target_include_directories(tests PRIVATE ${CMAKE_INSTALL_INCLUDEDIR} ${CMAKE_SOURCE_DIR}/tests)
308+
target_include_directories(tests PRIVATE
309+
${CMAKE_INSTALL_INCLUDEDIR}
310+
${CMAKE_SOURCE_DIR}/tests
311+
)
278312
add_dependencies(tests core_shared)
313+
279314
if(APPLE)
280315
target_link_options(tests PRIVATE "-Wl,-force_load,$<TARGET_FILE:core_shared>")
281316
endif()

include/array/array.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,9 @@ inline bool Array::hasDataOfType() const {
386386
template <typename T, ssize_t DIMS>
387387
inline py::detail::unchecked_reference<T, DIMS> Array::getAccessorOfReadOnlyData() const {
388388
if (!this->hasDataOfType<T>()) {
389-
throw py::type_error("Wrong requested type " + utils::getTypeName<T>());
389+
std::string msg = "Wrong requested type ";
390+
msg += utils::getTypeName<T>();
391+
throw py::type_error(msg);
390392
}
391393
if (static_cast<size_t>(DIMS) != this->dimensions()) {
392394
throw py::type_error("Expected dimensions: " + std::to_string(DIMS) +
@@ -398,7 +400,9 @@ inline py::detail::unchecked_reference<T, DIMS> Array::getAccessorOfReadOnlyData
398400
template <typename T, ssize_t DIMS>
399401
inline py::detail::unchecked_mutable_reference<T, DIMS> Array::getAccessorOfModifiableData() {
400402
if (!this->hasDataOfType<T>()) {
401-
throw py::type_error("Wrong requested type " + utils::getTypeName<T>());
403+
std::string msg = "Wrong requested type ";
404+
msg += utils::getTypeName<T>();
405+
throw py::type_error(msg);
402406
}
403407
if (static_cast<size_t>(DIMS) != this->dimensions()) {
404408
throw py::type_error("Expected dimensions: " + std::to_string(DIMS) +

include/array/assertions.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ class Array::Assertions {
3232
template <typename T>
3333
void haveDataOfType() const {
3434
if (!array.hasDataOfType<T>()) {
35-
throw py::type_error(
36-
"Wrong requested type " + utils::getTypeName<T>());
35+
std::string msg = "Wrong requested type ";
36+
msg += utils::getTypeName<T>();
37+
throw py::type_error(msg);
3738
}
3839
}
3940

include/utils/data_types.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33

44
# include <cstdint>
55
# include <string>
6+
#include <string_view>
7+
#include <type_traits>
68

79
namespace utils {
810

911
// Helper to get human-readable type names
1012
template <typename T>
11-
constexpr std::string getTypeName() {
13+
constexpr std::string_view getTypeName() {
1214
if constexpr (std::is_same_v<T, bool>) return "bool";
1315
else if constexpr (std::is_same_v<T, int8_t>) return "int8";
1416
else if constexpr (std::is_same_v<T, int16_t>) return "int16";
@@ -24,6 +26,10 @@ namespace utils {
2426
}
2527

2628
// TypeList for managing variadic type packs
29+
30+
template <typename T>
31+
struct TypeTag { using type = T; };
32+
2733
template <typename... T>
2834
struct TypeList {};
2935

include/utils/template_binder.hpp

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# include <pybind11/pybind11.h>
55
# include <string>
66
# include <type_traits>
7+
# include <utility>
78

89
# include "data_types.hpp"
910

@@ -13,45 +14,53 @@ namespace utils {
1314

1415

1516
// Generic function binder for all types in a TypeList
16-
template <typename... T>
17-
void bindForSpecifiedTypeList(py::module_ &m, const std::string &baseName, TypeList<T...>, auto functionTemplate) {
18-
(m.def((baseName + "_" + std::string(getTypeName<T>())).c_str(), functionTemplate.template operator()<T>()), ...);
17+
template <typename FunctionTemplate, typename... T>
18+
void bindForSpecifiedTypeList(
19+
py::module_ &m,
20+
const std::string &baseName,
21+
TypeList<T...>,
22+
FunctionTemplate&& functionTemplate) {
23+
(m.def(
24+
(baseName + "_" + std::string(getTypeName<T>())).c_str(),
25+
std::forward<FunctionTemplate>(functionTemplate).template operator()<T>(TypeTag<T>{})
26+
),
27+
...);
1928
}
2029

2130
// Helpers to bind functions for predefined TypeList (see data_types.hpp)
2231
template <typename FunctionTemplate>
23-
void bindForFloatingTypes(py::module_ &m, const std::string &baseName, FunctionTemplate functionTemplate) {
24-
bindForSpecifiedTypeList(m, baseName, FloatingTypes{}, functionTemplate);
32+
void bindForFloatingTypes(py::module_ &m, const std::string &baseName, FunctionTemplate&& ft) {
33+
bindForSpecifiedTypeList(m, baseName, FloatingTypes{}, std::forward<FunctionTemplate>(ft));
2534
}
2635

2736
template <typename FunctionTemplate>
28-
void bindForPositiveIntegralTypes(py::module_ &m, const std::string &baseName, FunctionTemplate functionTemplate) {
29-
bindForSpecifiedTypeList(m, baseName, PositiveIntegralTypes{}, functionTemplate);
37+
void bindForPositiveIntegralTypes(py::module_ &m, const std::string &baseName, FunctionTemplate&& ft) {
38+
bindForSpecifiedTypeList(m, baseName, PositiveIntegralTypes{}, std::forward<FunctionTemplate>(ft));
3039
}
3140

3241
template <typename FunctionTemplate>
33-
void bindForSignedIntegralTypes(py::module_ &m, const std::string &baseName, FunctionTemplate functionTemplate) {
34-
bindForSpecifiedTypeList(m, baseName, SignedIntegralTypes{}, functionTemplate);
42+
void bindForSignedIntegralTypes(py::module_ &m, const std::string &baseName, FunctionTemplate&& ft) {
43+
bindForSpecifiedTypeList(m, baseName, SignedIntegralTypes{}, std::forward<FunctionTemplate>(ft));
3544
}
3645

3746
template <typename FunctionTemplate>
38-
void bindForIntegralTypes(py::module_ &m, const std::string &baseName, FunctionTemplate functionTemplate) {
39-
bindForSpecifiedTypeList(m, baseName, IntegralTypes{}, functionTemplate);
47+
void bindForIntegralTypes(py::module_ &m, const std::string &baseName, FunctionTemplate&& ft) {
48+
bindForSpecifiedTypeList(m, baseName, IntegralTypes{}, std::forward<FunctionTemplate>(ft));
4049
}
4150

4251
template <typename FunctionTemplate>
43-
void bindForFloatingAndIntegralTypes(py::module_ &m, const std::string &baseName, FunctionTemplate functionTemplate) {
44-
bindForSpecifiedTypeList(m, baseName, FloatingAndIntegralTypes{}, functionTemplate);
52+
void bindForFloatingAndIntegralTypes(py::module_ &m, const std::string &baseName, FunctionTemplate&& ft) {
53+
bindForSpecifiedTypeList(m, baseName, FloatingAndIntegralTypes{}, std::forward<FunctionTemplate>(ft));
4554
}
4655

4756
template <typename FunctionTemplate>
48-
void bindForScalarTypes(py::module_ &m, const std::string &baseName, FunctionTemplate functionTemplate) {
49-
bindForSpecifiedTypeList(m, baseName, ScalarTypes{}, functionTemplate);
57+
void bindForScalarTypes(py::module_ &m, const std::string &baseName, FunctionTemplate&& ft) {
58+
bindForSpecifiedTypeList(m, baseName, ScalarTypes{}, std::forward<FunctionTemplate>(ft));
5059
}
5160

5261
template <typename FunctionTemplate>
53-
void bindForStringAndScalarTypes(py::module_ &m, const std::string &baseName, FunctionTemplate functionTemplate) {
54-
bindForSpecifiedTypeList(m, baseName, StringAndScalarTypes{}, functionTemplate);
62+
void bindForStringAndScalarTypes(py::module_ &m, const std::string &baseName, FunctionTemplate&& ft) {
63+
bindForSpecifiedTypeList(m, baseName, StringAndScalarTypes{}, std::forward<FunctionTemplate>(ft));
5564
}
5665

5766
}

src/c++/array/factory/matrices_pybind.hpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,28 @@ using namespace arrayfactory;
1010

1111
void bindFactoryOfMatricesArrays(py::module_ &m) {
1212

13-
utils::bindForScalarTypes(m, "full", []<typename T>() { return &full<T>; });
14-
15-
utils::bindForScalarTypes(m, "empty", []<typename T>() { return &empty<T>; });
16-
17-
utils::bindForScalarTypes(m, "computeStridesInOrderC", []<typename T>() { return &computeStridesInOrderC<T>; });
18-
utils::bindForScalarTypes(m, "computeStridesInOrderF", []<typename T>() { return &computeStridesInOrderF<T>; });
19-
20-
utils::bindForScalarTypes(m, "zeros", []<typename T>() { return &zeros<T>; });
21-
22-
utils::bindForScalarTypes(m, "ones", []<typename T>() { return &ones<T>; });
13+
utils::bindForScalarTypes(m, "full",
14+
[]<typename T>(utils::TypeTag<T>) { return &full<T>; }
15+
);
16+
17+
utils::bindForScalarTypes(m, "empty",
18+
[]<typename T>(utils::TypeTag<T>) { return &empty<T>; }
19+
);
20+
21+
utils::bindForScalarTypes(m, "computeStridesInOrderC",
22+
[]<typename T>(utils::TypeTag<T>) { return &computeStridesInOrderC<T>; }
23+
);
24+
utils::bindForScalarTypes(m, "computeStridesInOrderF",
25+
[]<typename T>(utils::TypeTag<T>) { return &computeStridesInOrderF<T>; }
26+
);
27+
28+
utils::bindForScalarTypes(m, "zeros",
29+
[]<typename T>(utils::TypeTag<T>) { return &zeros<T>; }
30+
);
31+
32+
utils::bindForScalarTypes(m, "ones",
33+
[]<typename T>(utils::TypeTag<T>) { return &ones<T>; }
34+
);
2335

2436
}
2537

src/c++/array/factory/vectors_pybind.hpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,13 @@ using namespace arrayfactory;
88

99
void bindFactoryOfVectorArrays(py::module_ &m) {
1010

11-
utils::bindForFloatingAndIntegralTypes(m,
12-
"uniformFromStep", []<typename T>() {
13-
return &uniformFromStep<T>;
14-
});
11+
utils::bindForFloatingAndIntegralTypes(m, "uniformFromStep",
12+
[]<typename T>(utils::TypeTag<T>) { return &uniformFromStep<T>; }
13+
);
1514

16-
utils::bindForFloatingTypes(m,
17-
"uniformFromCount", []<typename T>() {
18-
return &uniformFromCount<T>;
19-
});
15+
utils::bindForFloatingTypes(m, "uniformFromCount",
16+
[]<typename T>(utils::TypeTag<T>) { return &uniformFromCount<T>; }
17+
);
2018
}
2119

2220
# endif

tests/c++/array/factory/test_c_to_py.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@ template <typename... T>
1111
struct Instantiator {
1212
template <typename... U>
1313
void operator()() const {
14-
(static_cast<void>(test_from_carray_toArray1D<U>(bool{})), ...);
15-
(static_cast<void>(test_from_stdarray_toArray1D<U>(bool{})), ...);
16-
(static_cast<void>(test_from_vector_toArray1D<U>(bool{})), ...);
17-
(static_cast<void>(test_from_carray_toArray2D<U>(bool{})), ...);
18-
(static_cast<void>(test_from_stdarray_toArray2D<U>(bool{})), ...);
19-
(static_cast<void>(test_from_vector_toArray2D<U>(bool{})), ...);
20-
(static_cast<void>(test_from_carray_toArray3D<U>(bool{})), ...);
21-
(static_cast<void>(test_from_stdarray_toArray3D<U>(bool{})), ...);
22-
(static_cast<void>(test_from_vector_toArray3D<U>(bool{})), ...);
14+
(utils::forceSymbol(&test_from_carray_toArray1D<U>), ...);
15+
(utils::forceSymbol(&test_from_stdarray_toArray1D<U>), ...);
16+
(utils::forceSymbol(&test_from_vector_toArray1D<U>), ...);
17+
(utils::forceSymbol(&test_from_carray_toArray2D<U>), ...);
18+
(utils::forceSymbol(&test_from_stdarray_toArray2D<U>), ...);
19+
(utils::forceSymbol(&test_from_vector_toArray2D<U>), ...);
20+
(utils::forceSymbol(&test_from_carray_toArray3D<U>), ...);
21+
(utils::forceSymbol(&test_from_stdarray_toArray3D<U>), ...);
22+
(utils::forceSymbol(&test_from_vector_toArray3D<U>), ...);
2323
}
2424
};
2525

26-
template void utils::instantiateFromTypeList<Instantiator, utils::ScalarTypes>();
26+
2727

2828
// code
2929

@@ -257,3 +257,5 @@ void test_from_vector_toArray3D( bool copy ) {
257257
}
258258
}
259259

260+
261+
template void utils::instantiateFromTypeList<Instantiator, utils::ScalarTypes>();

tests/c++/array/factory/test_c_to_py_pybind.hpp

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,44 @@
55

66
void bindTestsOfFactoryOfArraysFromCToPy(py::module_ &m) {
77

8-
utils::bindForScalarTypes(m, "from_carray_toArray1D", []<typename T>() { return &test_from_carray_toArray1D<T>; });
9-
utils::bindForScalarTypes(m, "from_stdarray_toArray1D", []<typename T>() { return &test_from_stdarray_toArray1D<T>; });
10-
utils::bindForScalarTypes(m, "from_vector_toArray1D", []<typename T>() { return &test_from_vector_toArray1D<T>; });
8+
utils::bindForScalarTypes(m, "from_carray_toArray1D",
9+
[]<typename T>(utils::TypeTag<T>) { return &test_from_carray_toArray1D<T>; }
10+
);
1111

12-
utils::bindForScalarTypes(m, "from_carray_toArray2D", []<typename T>() { return &test_from_carray_toArray2D<T>; });
13-
utils::bindForScalarTypes(m, "from_stdarray_toArray2D", []<typename T>() { return &test_from_stdarray_toArray2D<T>; });
14-
utils::bindForScalarTypes(m, "from_vector_toArray2D", []<typename T>() { return &test_from_vector_toArray2D<T>; });
12+
utils::bindForScalarTypes(m, "from_stdarray_toArray1D",
13+
[]<typename T>(utils::TypeTag<T>) { return &test_from_stdarray_toArray1D<T>; }
14+
);
15+
16+
utils::bindForScalarTypes(m, "from_vector_toArray1D",
17+
[]<typename T>(utils::TypeTag<T>) { return &test_from_vector_toArray1D<T>; }
18+
);
19+
20+
21+
utils::bindForScalarTypes(m, "from_carray_toArray2D",
22+
[]<typename T>(utils::TypeTag<T>) { return &test_from_carray_toArray2D<T>; }
23+
);
24+
25+
utils::bindForScalarTypes(m, "from_stdarray_toArray2D",
26+
[]<typename T>(utils::TypeTag<T>) { return &test_from_stdarray_toArray2D<T>; }
27+
);
28+
29+
utils::bindForScalarTypes(m, "from_vector_toArray2D",
30+
[]<typename T>(utils::TypeTag<T>) { return &test_from_vector_toArray2D<T>; }
31+
);
32+
33+
34+
utils::bindForScalarTypes(m, "from_carray_toArray3D",
35+
[]<typename T>(utils::TypeTag<T>) { return &test_from_carray_toArray3D<T>; }
36+
);
37+
38+
utils::bindForScalarTypes(m, "from_stdarray_toArray3D",
39+
[]<typename T>(utils::TypeTag<T>) { return &test_from_stdarray_toArray3D<T>; }
40+
);
41+
42+
utils::bindForScalarTypes(m, "from_vector_toArray3D",
43+
[]<typename T>(utils::TypeTag<T>) { return &test_from_vector_toArray3D<T>; }
44+
);
1545

16-
utils::bindForScalarTypes(m, "from_carray_toArray3D", []<typename T>() { return &test_from_carray_toArray3D<T>; });
17-
utils::bindForScalarTypes(m, "from_stdarray_toArray3D", []<typename T>() { return &test_from_stdarray_toArray3D<T>; });
18-
utils::bindForScalarTypes(m, "from_vector_toArray3D", []<typename T>() { return &test_from_vector_toArray3D<T>; });
1946
}
2047

2148
# endif

tests/c++/array/factory/test_matrices.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,14 @@ template <typename... T>
186186
struct Instantiator {
187187
template <typename... U>
188188
void operator()() const {
189-
(static_cast<void>(test_zeros_c_order<U>()), ...);
190-
(static_cast<void>(test_zeros_f_order<U>()), ...);
191-
(static_cast<void>(test_ones_c_order<U>()), ...);
192-
(static_cast<void>(test_ones_f_order<U>()), ...);
193-
(static_cast<void>(test_full_c_order<U>()), ...);
194-
(static_cast<void>(test_full_f_order<U>()), ...);
195-
(static_cast<void>(test_empty_c_order<U>()), ...);
196-
(static_cast<void>(test_empty_f_order<U>()), ...);
189+
(utils::forceSymbol(&test_zeros_c_order<U>), ...);
190+
(utils::forceSymbol(&test_zeros_f_order<U>), ...);
191+
(utils::forceSymbol(&test_ones_c_order<U>), ...);
192+
(utils::forceSymbol(&test_ones_f_order<U>), ...);
193+
(utils::forceSymbol(&test_full_c_order<U>), ...);
194+
(utils::forceSymbol(&test_full_f_order<U>), ...);
195+
(utils::forceSymbol(&test_empty_c_order<U>), ...);
196+
(utils::forceSymbol(&test_empty_f_order<U>), ...);
197197
}
198198
};
199199

0 commit comments

Comments
 (0)