mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 05:05:11 +00:00
ci: Intel icc/icpc via oneAPI (#2573)
* CI: Intel icc/icpc via oneAPI Add testing for Intel icc/icpc via the oneAPI images. Intel oneAPI is in a late beta stage, currently shipping oneAPI beta09 with ICC 20.2. * CI: Skip Interpreter Tests for Intel Cannot find how to add this, neiter the package `libc6-dev` nor `intel-oneapi-mkl-devel` help when installed to solve this: ``` -- Looking for C++ include pthread.h -- Looking for C++ include pthread.h - not found CMake Error at /__t/cmake/3.18.4/x64/cmake-3.18.4-Linux-x86_64/share/cmake-3.18/Modules/FindPackageHandleStandardArgs.cmake:165 (message): Could NOT find Threads (missing: Threads_FOUND) Call Stack (most recent call first): /__t/cmake/3.18.4/x64/cmake-3.18.4-Linux-x86_64/share/cmake-3.18/Modules/FindPackageHandleStandardArgs.cmake:458 (_FPHSA_FAILURE_MESSAGE) /__t/cmake/3.18.4/x64/cmake-3.18.4-Linux-x86_64/share/cmake-3.18/Modules/FindThreads.cmake:234 (FIND_PACKAGE_HANDLE_STANDARD_ARGS) tests/test_embed/CMakeLists.txt:17 (find_package) ``` * CI: libc6-dev from GCC for ICC * CI: Run bare metal for oneAPI * CI: Ubuntu 18.04 for oneAPI * CI: Intel +Catch -Eigen * CI: CMake from Apt (ICC tests) * CI: Replace Intel Py with GCC Py * CI: Intel w/o GCC's Eigen * CI: ICC with verbose make * [Debug] Find core dump * tests: use arg{} instead of arg() for Intel * tests: adding a few more missing {} * fix: sync with @tobiasleibner's branch * fix: try ubuntu 20-04 * fix: drop exit 1 * style: clang tidy fix * style: fix missing NOLINT * ICC: Update Compiler Name Changed upstream with the last oneAPI release. * ICC CI: Downgrade pytest pytest 6 does not capture the `discard_as_unraisable` stderr and just writes a warning with its content instead. * Use new test pinning requirements.txt * tests: add notes about intel, cleanup Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
This commit is contained in:
parent
0f8d5f2eb6
commit
0b3df7f964
73
.github/workflows/ci.yml
vendored
73
.github/workflows/ci.yml
vendored
@ -412,6 +412,7 @@ jobs:
|
|||||||
- name: Interface test
|
- name: Interface test
|
||||||
run: cmake3 --build build --target test_cmake_build
|
run: cmake3 --build build --target test_cmake_build
|
||||||
|
|
||||||
|
|
||||||
# Testing on GCC using the GCC docker images (only recent images supported)
|
# Testing on GCC using the GCC docker images (only recent images supported)
|
||||||
gcc:
|
gcc:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -464,6 +465,78 @@ jobs:
|
|||||||
run: cmake --build build --target test_cmake_build
|
run: cmake --build build --target test_cmake_build
|
||||||
|
|
||||||
|
|
||||||
|
# Testing on ICC using the oneAPI apt repo
|
||||||
|
icc:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
|
||||||
|
name: "🐍 3 • ICC latest • x64"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Add apt repo
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y wget build-essential pkg-config cmake ca-certificates gnupg
|
||||||
|
wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
|
||||||
|
sudo apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
|
||||||
|
echo "deb https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list
|
||||||
|
|
||||||
|
- name: Add ICC & Python 3
|
||||||
|
run: sudo apt-get update; sudo apt-get install -y intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic cmake python3-dev python3-numpy python3-pytest python3-pip
|
||||||
|
|
||||||
|
- name: Update pip
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set +e; source /opt/intel/oneapi/setvars.sh; set -e
|
||||||
|
python3 -m pip install --upgrade pip
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
set +e; source /opt/intel/oneapi/setvars.sh; set -e
|
||||||
|
python3 -m pip install -r tests/requirements.txt --prefer-binary
|
||||||
|
|
||||||
|
- name: Configure
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set +e; source /opt/intel/oneapi/setvars.sh; set -e
|
||||||
|
cmake -S . -B build \
|
||||||
|
-DPYBIND11_WERROR=ON \
|
||||||
|
-DDOWNLOAD_CATCH=ON \
|
||||||
|
-DDOWNLOAD_EIGEN=OFF \
|
||||||
|
-DCMAKE_CXX_STANDARD=11 \
|
||||||
|
-DCMAKE_CXX_COMPILER=$(which icpc) \
|
||||||
|
-DCMAKE_VERBOSE_MAKEFILE=ON \
|
||||||
|
-DPYTHON_EXECUTABLE=$(python3 -c "import sys; print(sys.executable)")
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set +e; source /opt/intel/oneapi/setvars.sh; set -e
|
||||||
|
cmake --build build -j 2
|
||||||
|
|
||||||
|
- name: Python tests
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set +e; source /opt/intel/oneapi/setvars.sh; set -e
|
||||||
|
sudo service apport stop
|
||||||
|
cmake --build build --target check
|
||||||
|
|
||||||
|
- name: C++ tests
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set +e; source /opt/intel/oneapi/setvars.sh; set -e
|
||||||
|
cmake --build build --target cpptest
|
||||||
|
|
||||||
|
- name: Interface test
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set +e; source /opt/intel/oneapi/setvars.sh; set -e
|
||||||
|
cmake --build build --target test_cmake_build
|
||||||
|
|
||||||
|
|
||||||
# Testing on CentOS (manylinux uses a centos base, and this is an easy way
|
# Testing on CentOS (manylinux uses a centos base, and this is an easy way
|
||||||
# to get GCC 4.8, which is the manylinux1 compiler).
|
# to get GCC 4.8, which is the manylinux1 compiler).
|
||||||
centos:
|
centos:
|
||||||
|
@ -183,9 +183,11 @@ TEST_SUBMODULE(builtin_casters, m) {
|
|||||||
m.def("load_nullptr_t", [](std::nullptr_t) {}); // not useful, but it should still compile
|
m.def("load_nullptr_t", [](std::nullptr_t) {}); // not useful, but it should still compile
|
||||||
m.def("cast_nullptr_t", []() { return std::nullptr_t{}; });
|
m.def("cast_nullptr_t", []() { return std::nullptr_t{}; });
|
||||||
|
|
||||||
|
// [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.
|
||||||
|
|
||||||
// test_bool_caster
|
// test_bool_caster
|
||||||
m.def("bool_passthrough", [](bool arg) { return arg; });
|
m.def("bool_passthrough", [](bool arg) { return arg; });
|
||||||
m.def("bool_passthrough_noconvert", [](bool arg) { return arg; }, py::arg().noconvert());
|
m.def("bool_passthrough_noconvert", [](bool arg) { return arg; }, py::arg{}.noconvert());
|
||||||
|
|
||||||
// test_reference_wrapper
|
// test_reference_wrapper
|
||||||
m.def("refwrap_builtin", [](std::reference_wrapper<int> p) { return 10 * p.get(); });
|
m.def("refwrap_builtin", [](std::reference_wrapper<int> p) { return 10 * p.get(); });
|
||||||
|
@ -119,7 +119,8 @@ TEST_SUBMODULE(callbacks, m) {
|
|||||||
|
|
||||||
class AbstractBase {
|
class AbstractBase {
|
||||||
public:
|
public:
|
||||||
virtual ~AbstractBase() = default;
|
// [workaround(intel)] = default does not work here
|
||||||
|
virtual ~AbstractBase() {}; // NOLINT(modernize-use-equals-default)
|
||||||
virtual unsigned int func() = 0;
|
virtual unsigned int func() = 0;
|
||||||
};
|
};
|
||||||
m.def("func_accepting_func_accepting_base", [](std::function<double(AbstractBase&)>) { });
|
m.def("func_accepting_func_accepting_base", [](std::function<double(AbstractBase&)>) { });
|
||||||
|
@ -323,6 +323,8 @@ TEST_SUBMODULE(class_, m) {
|
|||||||
|
|
||||||
class PublicistB : public ProtectedB {
|
class PublicistB : public ProtectedB {
|
||||||
public:
|
public:
|
||||||
|
// [workaround(intel)] = default does not work here
|
||||||
|
~PublicistB() override {}; // NOLINT(modernize-use-equals-default)
|
||||||
using ProtectedB::foo;
|
using ProtectedB::foo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -99,19 +99,20 @@ TEST_SUBMODULE(custom_type_casters, m) {
|
|||||||
}
|
}
|
||||||
static ArgInspector2 h(ArgInspector2 a, ArgAlwaysConverts) { return a; }
|
static ArgInspector2 h(ArgInspector2 a, ArgAlwaysConverts) { return a; }
|
||||||
};
|
};
|
||||||
|
// [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.
|
||||||
py::class_<ArgInspector>(m, "ArgInspector")
|
py::class_<ArgInspector>(m, "ArgInspector")
|
||||||
.def(py::init<>())
|
.def(py::init<>())
|
||||||
.def("f", &ArgInspector::f, py::arg(), py::arg() = ArgAlwaysConverts())
|
.def("f", &ArgInspector::f, py::arg(), py::arg() = ArgAlwaysConverts())
|
||||||
.def("g", &ArgInspector::g, "a"_a.noconvert(), "b"_a, "c"_a.noconvert()=13, "d"_a=ArgInspector2(), py::arg() = ArgAlwaysConverts())
|
.def("g", &ArgInspector::g, "a"_a.noconvert(), "b"_a, "c"_a.noconvert()=13, "d"_a=ArgInspector2(), py::arg() = ArgAlwaysConverts())
|
||||||
.def_static("h", &ArgInspector::h, py::arg().noconvert(), py::arg() = ArgAlwaysConverts())
|
.def_static("h", &ArgInspector::h, py::arg{}.noconvert(), py::arg() = ArgAlwaysConverts())
|
||||||
;
|
;
|
||||||
m.def("arg_inspect_func", [](ArgInspector2 a, ArgInspector1 b, ArgAlwaysConverts) { return a.arg + "\n" + b.arg; },
|
m.def("arg_inspect_func", [](ArgInspector2 a, ArgInspector1 b, ArgAlwaysConverts) { return a.arg + "\n" + b.arg; },
|
||||||
py::arg().noconvert(false), py::arg_v(nullptr, ArgInspector1()).noconvert(true), py::arg() = ArgAlwaysConverts());
|
py::arg{}.noconvert(false), py::arg_v(nullptr, ArgInspector1()).noconvert(true), py::arg() = ArgAlwaysConverts());
|
||||||
|
|
||||||
m.def("floats_preferred", [](double f) { return 0.5 * f; }, py::arg("f"));
|
m.def("floats_preferred", [](double f) { return 0.5 * f; }, "f"_a);
|
||||||
m.def("floats_only", [](double f) { return 0.5 * f; }, py::arg("f").noconvert());
|
m.def("floats_only", [](double f) { return 0.5 * f; }, "f"_a.noconvert());
|
||||||
m.def("ints_preferred", [](int i) { return i / 2; }, py::arg("i"));
|
m.def("ints_preferred", [](int i) { return i / 2; }, "i"_a);
|
||||||
m.def("ints_only", [](int i) { return i / 2; }, py::arg("i").noconvert());
|
m.def("ints_only", [](int i) { return i / 2; }, "i"_a.noconvert());
|
||||||
|
|
||||||
// test_custom_caster_destruction
|
// test_custom_caster_destruction
|
||||||
// Test that `take_ownership` works on types with a custom type caster when given a pointer
|
// Test that `take_ownership` works on types with a custom type caster when given a pointer
|
||||||
|
@ -273,6 +273,7 @@ TEST_SUBMODULE(eigen, m) {
|
|||||||
m.def("cpp_ref_r", [](py::handle m) { return m.cast<Eigen::Ref<MatrixXdR>>()(1, 0); });
|
m.def("cpp_ref_r", [](py::handle m) { return m.cast<Eigen::Ref<MatrixXdR>>()(1, 0); });
|
||||||
m.def("cpp_ref_any", [](py::handle m) { return m.cast<py::EigenDRef<Eigen::MatrixXd>>()(1, 0); });
|
m.def("cpp_ref_any", [](py::handle m) { return m.cast<py::EigenDRef<Eigen::MatrixXd>>()(1, 0); });
|
||||||
|
|
||||||
|
// [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.
|
||||||
|
|
||||||
// test_nocopy_wrapper
|
// test_nocopy_wrapper
|
||||||
// Test that we can prevent copying into an argument that would normally copy: First a version
|
// Test that we can prevent copying into an argument that would normally copy: First a version
|
||||||
@ -280,17 +281,17 @@ TEST_SUBMODULE(eigen, m) {
|
|||||||
m.def("get_elem", &get_elem);
|
m.def("get_elem", &get_elem);
|
||||||
// Now this alternative that calls the tells pybind to fail rather than copy:
|
// Now this alternative that calls the tells pybind to fail rather than copy:
|
||||||
m.def("get_elem_nocopy", [](Eigen::Ref<const Eigen::MatrixXd> m) -> double { return get_elem(m); },
|
m.def("get_elem_nocopy", [](Eigen::Ref<const Eigen::MatrixXd> m) -> double { return get_elem(m); },
|
||||||
py::arg().noconvert());
|
py::arg{}.noconvert());
|
||||||
// Also test a row-major-only no-copy const ref:
|
// Also test a row-major-only no-copy const ref:
|
||||||
m.def("get_elem_rm_nocopy", [](Eigen::Ref<const Eigen::Matrix<long, -1, -1, Eigen::RowMajor>> &m) -> long { return m(2, 1); },
|
m.def("get_elem_rm_nocopy", [](Eigen::Ref<const Eigen::Matrix<long, -1, -1, Eigen::RowMajor>> &m) -> long { return m(2, 1); },
|
||||||
py::arg().noconvert());
|
py::arg{}.noconvert());
|
||||||
|
|
||||||
// test_issue738
|
// test_issue738
|
||||||
// Issue #738: 1xN or Nx1 2D matrices were neither accepted nor properly copied with an
|
// Issue #738: 1xN or Nx1 2D matrices were neither accepted nor properly copied with an
|
||||||
// incompatible stride value on the length-1 dimension--but that should be allowed (without
|
// incompatible stride value on the length-1 dimension--but that should be allowed (without
|
||||||
// requiring a copy!) because the stride value can be safely ignored on a size-1 dimension.
|
// requiring a copy!) because the stride value can be safely ignored on a size-1 dimension.
|
||||||
m.def("iss738_f1", &adjust_matrix<const Eigen::Ref<const Eigen::MatrixXd> &>, py::arg().noconvert());
|
m.def("iss738_f1", &adjust_matrix<const Eigen::Ref<const Eigen::MatrixXd> &>, py::arg{}.noconvert());
|
||||||
m.def("iss738_f2", &adjust_matrix<const Eigen::Ref<const Eigen::Matrix<double, -1, -1, Eigen::RowMajor>> &>, py::arg().noconvert());
|
m.def("iss738_f2", &adjust_matrix<const Eigen::Ref<const Eigen::Matrix<double, -1, -1, Eigen::RowMajor>> &>, py::arg{}.noconvert());
|
||||||
|
|
||||||
// test_issue1105
|
// test_issue1105
|
||||||
// Issue #1105: when converting from a numpy two-dimensional (Nx1) or (1xN) value into a dense
|
// Issue #1105: when converting from a numpy two-dimensional (Nx1) or (1xN) value into a dense
|
||||||
|
@ -322,22 +322,24 @@ TEST_SUBMODULE(methods_and_attributes, m) {
|
|||||||
m.def("should_fail", [](int, UnregisteredType) {}, py::arg(), py::arg() = UnregisteredType());
|
m.def("should_fail", [](int, UnregisteredType) {}, py::arg(), py::arg() = UnregisteredType());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.
|
||||||
|
|
||||||
// test_accepts_none
|
// test_accepts_none
|
||||||
py::class_<NoneTester, std::shared_ptr<NoneTester>>(m, "NoneTester")
|
py::class_<NoneTester, std::shared_ptr<NoneTester>>(m, "NoneTester")
|
||||||
.def(py::init<>());
|
.def(py::init<>());
|
||||||
m.def("no_none1", &none1, py::arg().none(false));
|
m.def("no_none1", &none1, py::arg{}.none(false));
|
||||||
m.def("no_none2", &none2, py::arg().none(false));
|
m.def("no_none2", &none2, py::arg{}.none(false));
|
||||||
m.def("no_none3", &none3, py::arg().none(false));
|
m.def("no_none3", &none3, py::arg{}.none(false));
|
||||||
m.def("no_none4", &none4, py::arg().none(false));
|
m.def("no_none4", &none4, py::arg{}.none(false));
|
||||||
m.def("no_none5", &none5, py::arg().none(false));
|
m.def("no_none5", &none5, py::arg{}.none(false));
|
||||||
m.def("ok_none1", &none1);
|
m.def("ok_none1", &none1);
|
||||||
m.def("ok_none2", &none2, py::arg().none(true));
|
m.def("ok_none2", &none2, py::arg{}.none(true));
|
||||||
m.def("ok_none3", &none3);
|
m.def("ok_none3", &none3);
|
||||||
m.def("ok_none4", &none4, py::arg().none(true));
|
m.def("ok_none4", &none4, py::arg{}.none(true));
|
||||||
m.def("ok_none5", &none5);
|
m.def("ok_none5", &none5);
|
||||||
|
|
||||||
m.def("no_none_kwarg", &none2, py::arg("a").none(false));
|
m.def("no_none_kwarg", &none2, "a"_a.none(false));
|
||||||
m.def("no_none_kwarg_kw_only", &none2, py::kw_only(), py::arg("a").none(false));
|
m.def("no_none_kwarg_kw_only", &none2, py::kw_only(), "a"_a.none(false));
|
||||||
|
|
||||||
// test_str_issue
|
// test_str_issue
|
||||||
// Issue #283: __str__ called on uninitialized instance when constructor arguments invalid
|
// Issue #283: __str__ called on uninitialized instance when constructor arguments invalid
|
||||||
|
@ -258,9 +258,11 @@ TEST_SUBMODULE(numpy_array, sm) {
|
|||||||
sm.def("overloaded2", [](py::array_t<std::complex<float>>) { return "float complex"; });
|
sm.def("overloaded2", [](py::array_t<std::complex<float>>) { return "float complex"; });
|
||||||
sm.def("overloaded2", [](py::array_t<float>) { return "float"; });
|
sm.def("overloaded2", [](py::array_t<float>) { return "float"; });
|
||||||
|
|
||||||
|
// [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.
|
||||||
|
|
||||||
// Only accept the exact types:
|
// Only accept the exact types:
|
||||||
sm.def("overloaded3", [](py::array_t<int>) { return "int"; }, py::arg().noconvert());
|
sm.def("overloaded3", [](py::array_t<int>) { return "int"; }, py::arg{}.noconvert());
|
||||||
sm.def("overloaded3", [](py::array_t<double>) { return "double"; }, py::arg().noconvert());
|
sm.def("overloaded3", [](py::array_t<double>) { return "double"; }, py::arg{}.noconvert());
|
||||||
|
|
||||||
// Make sure we don't do unsafe coercion (e.g. float to int) when not using forcecast, but
|
// Make sure we don't do unsafe coercion (e.g. float to int) when not using forcecast, but
|
||||||
// rather that float gets converted via the safe (conversion to double) overload:
|
// rather that float gets converted via the safe (conversion to double) overload:
|
||||||
@ -284,7 +286,7 @@ TEST_SUBMODULE(numpy_array, sm) {
|
|||||||
for (py::ssize_t i = 0; i < r.shape(0); i++)
|
for (py::ssize_t i = 0; i < r.shape(0); i++)
|
||||||
for (py::ssize_t j = 0; j < r.shape(1); j++)
|
for (py::ssize_t j = 0; j < r.shape(1); j++)
|
||||||
r(i, j) += v;
|
r(i, j) += v;
|
||||||
}, py::arg().noconvert(), py::arg());
|
}, py::arg{}.noconvert(), py::arg());
|
||||||
|
|
||||||
sm.def("proxy_init3", [](double start) {
|
sm.def("proxy_init3", [](double start) {
|
||||||
py::array_t<double, py::array::c_style> a({ 3, 3, 3 });
|
py::array_t<double, py::array::c_style> a({ 3, 3, 3 });
|
||||||
@ -338,7 +340,7 @@ TEST_SUBMODULE(numpy_array, sm) {
|
|||||||
for (py::ssize_t i = 0; i < r.shape(0); i++)
|
for (py::ssize_t i = 0; i < r.shape(0); i++)
|
||||||
for (py::ssize_t j = 0; j < r.shape(1); j++)
|
for (py::ssize_t j = 0; j < r.shape(1); j++)
|
||||||
r(i, j) += v;
|
r(i, j) += v;
|
||||||
}, py::arg().noconvert(), py::arg());
|
}, py::arg{}.noconvert(), py::arg());
|
||||||
sm.def("proxy_init3_dyn", [](double start) {
|
sm.def("proxy_init3_dyn", [](double start) {
|
||||||
py::array_t<double, py::array::c_style> a({ 3, 3, 3 });
|
py::array_t<double, py::array::c_style> a({ 3, 3, 3 });
|
||||||
auto r = a.mutable_unchecked();
|
auto r = a.mutable_unchecked();
|
||||||
@ -419,20 +421,20 @@ TEST_SUBMODULE(numpy_array, sm) {
|
|||||||
py::arg("a"));
|
py::arg("a"));
|
||||||
sm.def("accept_double_noconvert",
|
sm.def("accept_double_noconvert",
|
||||||
[](py::array_t<double, 0>) {},
|
[](py::array_t<double, 0>) {},
|
||||||
py::arg("a").noconvert());
|
"a"_a.noconvert());
|
||||||
sm.def("accept_double_forcecast_noconvert",
|
sm.def("accept_double_forcecast_noconvert",
|
||||||
[](py::array_t<double, py::array::forcecast>) {},
|
[](py::array_t<double, py::array::forcecast>) {},
|
||||||
py::arg("a").noconvert());
|
"a"_a.noconvert());
|
||||||
sm.def("accept_double_c_style_noconvert",
|
sm.def("accept_double_c_style_noconvert",
|
||||||
[](py::array_t<double, py::array::c_style>) {},
|
[](py::array_t<double, py::array::c_style>) {},
|
||||||
py::arg("a").noconvert());
|
"a"_a.noconvert());
|
||||||
sm.def("accept_double_c_style_forcecast_noconvert",
|
sm.def("accept_double_c_style_forcecast_noconvert",
|
||||||
[](py::array_t<double, py::array::forcecast | py::array::c_style>) {},
|
[](py::array_t<double, py::array::forcecast | py::array::c_style>) {},
|
||||||
py::arg("a").noconvert());
|
"a"_a.noconvert());
|
||||||
sm.def("accept_double_f_style_noconvert",
|
sm.def("accept_double_f_style_noconvert",
|
||||||
[](py::array_t<double, py::array::f_style>) {},
|
[](py::array_t<double, py::array::f_style>) {},
|
||||||
py::arg("a").noconvert());
|
"a"_a.noconvert());
|
||||||
sm.def("accept_double_f_style_forcecast_noconvert",
|
sm.def("accept_double_f_style_forcecast_noconvert",
|
||||||
[](py::array_t<double, py::array::forcecast | py::array::f_style>) {},
|
[](py::array_t<double, py::array::forcecast | py::array::f_style>) {},
|
||||||
py::arg("a").noconvert());
|
"a"_a.noconvert());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user