-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Intel ICC C++17 compatibility #2729
Conversation
Thanks for creating the PR! Maybe you can add a comment to your fix explaining why it is needed? Just a short sentence similar to the comments I added to my changes. You should probably rebase on/merge in the master branch, maybe that fixes some of the non-ICC failures in CI. Not sure what the test failure in the ICC branches is about, I think I haven't seen that error before. |
Thanks for the comment. I added a note about the internal compiler error and merged master (still getting unrelated CI errors though). It might make sense to wait for #2573 to be merged first and then squash/rebase the present pull request to eliminate the overlap. |
Rebase is needed. Plus there's that extra empty line in the yaml file. |
CI always bases "PR" builds on the latest master when it changes (including when it reopens). I think the empty line was in a different PR and I fixed it already. |
Oh, you mean it needs to be rebased after #2573? Yes, apparently so. |
No, no. I thought it needed a rebase after fixing the CI. The
Therefore, ICC is well within its rights to disregard the extended alignment request. Granted, the standard says ill-formed, not ill-formed, no diagnostic required. At least according to cppreference, ICC is required to display a warning. For what it's worth, we asked for a 1024-byte alignment and we got 16-byte alignment. |
On the other hand, compiler explorer says that 1024-byte alignment works fine in ICC 21.1. |
Okay, so what do we do about the alignment test? I played around with it a bit yesterday and was unable to fix it, but also unable to reproduce outside pybind11. Disable it on Intel? |
https://github.com/pybind/pybind11/blob/master/tests/test_class.cpp#L392-L399 Maybe just add #include <Python.h>
struct alignas(1024) Aligned {
uintptr_t ptr() { return (uintptr_t)this; }
};
typedef struct {
PyObject_HEAD
Aligned* aligned;
} PyAligned;
static void PyAligned_dealloc(PyAligned *self) {
delete self->aligned;
Py_TYPE(self)->tp_free((PyObject *) self);
}
static PyObject * PyAligned_ptr(PyAligned *self, PyObject *Py_UNUSED(ignored)) {
if (self->aligned == NULL) {
PyErr_SetString(PyExc_AttributeError, "aligned");
return NULL;
}
return PyLong_FromUnsignedLong(self->aligned->ptr());
}
static PyObject * PyAligned_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
PyAligned *self = (PyAligned *) type->tp_alloc(type, 0);
if (self != NULL) self->aligned = new Aligned;
return (PyObject *) self;
}
static PyMethodDef PyAligned_methods[] = {
{"ptr", (PyCFunction) PyAligned_ptr, METH_NOARGS},
{NULL} /* Sentinel */
};
static PyTypeObject AlignedType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "t.Aligned",
.tp_basicsize = sizeof(PyAligned),
.tp_itemsize = 0,
.tp_dealloc = (destructor) PyAligned_dealloc,
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
.tp_methods = PyAligned_methods,
.tp_new = PyAligned_new,
};
static PyModuleDef tmodule = {
PyModuleDef_HEAD_INIT,
.m_name = "t",
.m_size = -1,
};
PyMODINIT_FUNC PyInit_t(void) {
if (PyType_Ready(&AlignedType) < 0)
return NULL;
PyObject* m = PyModule_Create(&tmodule);
if (m == NULL) return NULL;
Py_INCREF(&AlignedType);
if (PyModule_AddObject(m, "Aligned", (PyObject *) &AlignedType) < 0) {
Py_DECREF(&AlignedType);
Py_DECREF(m);
return NULL;
}
return m;
} Test with:
One difference between what pybind11 is doing and what the above (almost) C is doing is how the bindings are made. Pybind11 adds an empty type object to the module object and then adds python methods to modules or types, as it encounters |
So it's not aligned either. I'll add the |
The remaining test failure, is also present in the C++11 ICC run. I'm not sure what's going on there. As for the alignment problem, here's a tiny example that repro's the problem: https://godbolt.org/z/MYj5r5 Sure enough, libstdc++ protects the aligned cppreference says that ICC supports aligned |
Excellent find! If I add the lie to your pybind11-less example from earlier today, it aligns correctly. What would you think about adding #if defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1900 && defined(PYBIND11_CPP17)
// Intel compiler doesn't advertise that it supports alignas, so libstdc++ doesn't
// enable the aligned new operators by default.
#define __cpp_aligned_new 1
#endif somewhere near pybind11/include/pybind11/detail/common.h Line 104 in 7bd4b39 |
I was wary about suggesting that. I'm not sure what would happen if one translation contained that lie but another did not and both tried to use overaligned types? We would still be in ill-formed land, with a bit of ODR violations sprinkled around? Would it be possible to construct a case where one TU would think the pointer is overaligned when it really isn't? That's why I don't want to make the decision and would rather let others chime in with their thoughts. |
I've found an alternative and less hacky solution: adding Since this is Intel's official (and not standard-compliant) way of requesting aligned new support, I guess the correct thing for us to do would be to not add |
That header, at least on linux, overrides the aligned new operators and makes them a thin wrapper around
Does ICC support |
It does, but anyone using
Regarding that failing test_python_alreadyset_in_destructor: I cannot reproduce the problem locally. |
I'd be okay just to disable that test for now (for Intel) to get this in. |
Okay, skipping the test now. I don't really understand how the exception handling works, so I don't think I would have been able to fix it. Perhaps the original author of that test (@jbarlow83, #2372) has an idea and could fix it at some later point. Thanks for milestoning, looking forward to seeing full Intel support in a release soon. |
Looks like aligned is acting up again? |
|
@jbarlow83: I cannot reproduce this error locally, so I can only answer your first question from the CI build log:
|
Sorry about that, I put the |
What failed was our test for whether an appropriate error message was sent to stderr. I suspect it's related to the version of pytest or somehow CI-related. It should be compiler independent. (The traceback is not a concern. That part is supposed to happen.) |
@jbarlow83, I could not reproduce this on Ubuntu 18.04 after upgrading pytest to the same version as provided by Ubuntu 20.04. I also could not reproduce it on Ubuntu 20.04 with GCC instead of Intel ICC (I don't have Intel available on that machine). The NVCC job in CI is also running on Ubuntu 20.04 though, so it would have the exact same Python environment as the ICC job, yet it does not exhibit the problem -- so there might be some compiler dependency. No idea why the choice of compiler should affect the capturing of stderr inside pytest though. |
Is there a way to pin a version? This seems to just pull "latest", which could change and break our tests. |
We need a sign off from @wjakob for this one. He’s worried about worried about working around bugs in the Intel compiler instead of getting Intel to fix their bugs. If we provide a clear path forward, that will help. Tomorrow I’m going to see if the old ifdef workarounds are still needed. If we can drop a few workarounds while adding more, that will help. Yannicks idea for cataloging workarounds could help too. I’ll also try to see if I can get the bugs reported to Intel if I don’t have an issue number for them (I have very few currently, maybe one). |
@jeffhammond are your compiler folks interested in triaging those oneAPI |
C++17 compiler bug request submitted as intel bug 04916230 on https://supporttickets.intel.com |
Which bug is this? The
(This would be a great use for GitHub Discussions, actually ;) ) |
Yes, the |
Will do. I‘ll squash the commits into one per bug report and add the bug numbers to the commit messages. Could you please also file a bug report for the internal compiler error in |
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 docs: Apply suggestions from code review Co-authored-by: Tobias Leibner <[email protected]> Workaround for ICC enable_if issues Another workaround for ICC's enable_if issues fix error in previous commit Disable one test for the Intel compiler in C++17 mode Add back one instance of py::arg().noconvert() Add NOLINT to fix clang-tidy check Work around for ICC internal error in PYBIND11_EXPAND_SIDE_EFFECTS in C++17 mode CI: Intel ICC with C++17 docs: pybind11/numpy.h does not require numpy at build time. (#2720) This is nice enough to be mentioned explicitly in the docs. docs: Update warning about Python 3.9.0 UB, now that 3.9.1 has been released (#2719) Adjusting `type_caster<std::reference_wrapper<T>>` to support const/non-const propagation in `cast_op`. (#2705) * Allow type_caster of std::reference_wrapper<T> to be the same as a native reference. Before, both std::reference_wrapper<T> and std::reference_wrapper<const T> would invoke cast_op<type>. This doesn't allow the type_caster<> specialization for T to distinguish reference_wrapper types from value types. After, the type_caster<> specialization invokes cast_op<type&>, which allows reference_wrapper to behave in the same way as a native reference type. * Add tests/examples for std::reference_wrapper<const T> * Add tests which use mutable/immutable variants This test is a chimera; it blends the pybind11 casters with a custom pytype implementation that supports immutable and mutable calls. In order to detect the immutable/mutable state, the cast_op needs to propagate it, even through e.g. std::reference<const T> Note: This is still a work in progress; some things are crashing, which likely means that I have a refcounting bug or something else missing. * Add/finish tests that distinguish const& from & Fixes the bugs in my custom python type implementation, demonstrate test that requires const& and reference_wrapper<const T> being treated differently from Non-const. * Add passing a const to non-const method. * Demonstrate non-const conversion of reference_wrapper in tests. Apply formatting presubmit check. * Fix build errors from presubmit checks. * Try and fix a few more CI errors * More CI fixes. * More CI fixups. * Try and get PyPy to work. * Additional minor fixups. Getting close to CI green. * More ci fixes? * fix clang-tidy warnings from presubmit * fix more clang-tidy warnings * minor comment and consistency cleanups * PyDECREF -> Py_DECREF * copy/move constructors * Resolve codereview comments * more review comment fixes * review comments: remove spurious & * Make the test fail even when the static_assert is commented out. This expands the test_freezable_type_caster a bit by: 1/ adding accessors .is_immutable and .addr to compare identity from python. 2/ Changing the default cast_op of the type_caster<> specialization to return a non-const value. In normal codepaths this is a reasonable default. 3/ adding roundtrip variants to exercise the by reference, by pointer and by reference_wrapper in all call paths. In conjunction with 2/, this demonstrates the failure case of the existing std::reference_wrpper conversion, which now loses const in a similar way that happens when using the default cast_op_type<>. * apply presubmit formatting * Revert inclusion of test_freezable_type_caster There's some concern that this test is a bit unwieldly because of the use of the raw <Python.h> functions. Removing for now. * Add a test that validates const references propagation. This test verifies that cast_op may be used to correctly detect const reference types when used with std::reference_wrapper. * mend * Review comments based changes. 1. std::add_lvalue_reference<type> -> type& 2. Simplify the test a little more; we're never returning the ConstRefCaster type so the class_ definition can be removed. * formatted files again. * Move const_ref_caster test to builtin_casters * Review comments: use cast_op and adjust some comments. * Simplify ConstRefCasted test I like this version better as it moves the assertion that matters back into python. ci: drop pypy2 linux, PGI 20.7, add Python 10 dev (#2724) * ci: drop pypy2 linux, add Python 10 dev * ci: fix mistake * ci: commented-out PGI 20.11, drop 20.7 fix: regression with installed pybind11 overriding local one (#2716) * fix: regression with installed pybind11 overriding discovered one Closes #2709 * docs: wording incorrect style: remove redundant instance->owned = true (#2723) which was just before set to True in instance->allocate_layout() fix: also throw in the move-constructor added by the PYBIND11_OBJECT macro, after the argument has been moved-out (if necessary) (#2701) Make args_are_all_* ICC workarounds unconditional Disable test_aligned on Intel ICC Fix test_aligned on Intel ICC Skip test_python_alreadyset_in_destructor on Intel ICC Fix test_aligned again ICC CI: Downgrade pytest pytest 6 does not capture the `discard_as_unraisable` stderr and just writes a warning with its content instead.
@bstaletic @YannickJadoul Any idea why MSVC hates my final commit, but everybody else is fine with it, and it looks pretty much like what we are already doing? f9ccfd2 |
@henryiii, what about using EDIT: Well, I now see that's going back to what we +- had, so probably not :-( |
Interesting, so MSVC gets a different |
To state the obvious: the difference with the working example above is that Is there a way we can add this as an argument? Or maybe in two steps, with an |
MSVC not liking valid templates in C++17 usually smells of a missing |
It should be there in some places, and it's also failing in 14. It's failing for all MSVC, 2015, 2017, and 2019. |
I think I came up with an |
Okay, ready for a review. I've cleaned up the one ugly workaround, and added greppable comments and such, and listed the three workarounds implemented at the top of the PR. |
} | ||
|
||
// [workaround(intel)] Separate function required here | ||
// [workaround(msvc)] Can't use constexpr bool in return type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is MSVC failing on the constexpr
or on the combination with std::enable_if
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original all-in-one was too complicated for ICC to compile. Refactoring it to match the others, with a constexpr function, confused MSVC if it was in the return type. This is simpler to compile and avoids a constexpr function in a return type. As I don't think that this function is an external interface, and it's only used here, I could avoid the intermediate function and call the "impl" style function directly, if that's seen as cleaner.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After #2573, I think this one can go in as well. Workarounds are never pretty, but let's hope we can get rid of them soon enough, if Intel is working on it :-)
Adds C++17 support.
enable_if_t<all_of<is_positional<Args>...>::value>>
, but if it is refactored into a separate constexpr function, it works.noexcept
can cause weird errors with following syntax,noexcept(true)
works fine, workaround in testsThis also fixes the NVIDIA HPC SDK compiler in C++17 mode.
Description
The Intel compiler has trouble with pybind11 when compiling in C++17 mode. The first two examples in the code below result in errors like "no instance of function template [...] matches the argument list", while the third one triggers an internal compiler error.
Details can be found in #2707. @tobiasleibner implemented the fix for the template mismatch, while the workaround for the internal compiler error is mine. Part of @tobiasleibner's work went into #2573 already, which hasn't been merged yet. Since he currently doesn't have time, he suggested I post a pull request.
Related to #2573
Fixes #2714
Fixes #2707
Suggested changelog entry: