-
Notifications
You must be signed in to change notification settings - Fork 13
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
Replaces CFFI bindings by pybind11 bindings #10
Conversation
…low for binary wheels compile, modifies setup to use pyproject file
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.
Thanks a lot, this looks like a great step forward. I left a couple of first comments here and there. Some are nitpicks – not blocking this PR, but should be sorted out eventually.
I will be off for vacation and might not be able to respond within the next week.
@tuxu Thanks for the feedback, that's great! I was also on holiday and I will now get back onto this. |
Co-authored-by: Tino Wagner <[email protected]>
… into pybind11-refactor
…ds libsamplerate version in package.
@tuxu I have updated the doc, docstrings, and the README. Could you please give it a look when you have time? |
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.
@fakufaku This looks great.
I added a commit which fixes the build of the documentation and another one which passes the package version into the CMake build. I don't see any bigger blockers right now.
src/samplerate.cpp
Outdated
// create a shorter view of the array | ||
if ((size_t)src_data.output_frames_gen < new_size) { | ||
out_shape[0] = src_data.output_frames_gen; | ||
output = py::array_t<float, py::array::c_style>( | ||
out_shape, static_cast<float *>(outbuf.ptr)); |
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.
I was unsure about the lifetimes of the data at outbuf.ptr
here and elsewhere in the code. However, it turned out this creates not a view of the data but a copy instead. This is safe, but it would be a good future optimization to avoid that copy.
NB: Running the tests with address sanitizers (-fsanitize-address
) passed without issues 🎉
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.
I think that we can replace this by
output.resize(out_shape);
As I understand it, it should avoid the copy.
Also, it is still the same object, so there should not be any data ownership problem.
Here is the definition of the resize
function (source).
void resize(ShapeContainer new_shape, bool refcheck = true) {
detail::npy_api::PyArray_Dims d
= {// Use reinterpret_cast for PyPy on Windows (remove if fixed, checked on 7.3.1)
reinterpret_cast<Py_intptr_t *>(new_shape->data()),
int(new_shape->size())};
// try to resize, set ordering param to -1 cause it's not used anyway
auto new_array = reinterpret_steal<object>(
detail::npy_api::get().PyArray_Resize_(m_ptr, &d, int(refcheck), -1));
if (!new_array) {
throw error_already_set();
}
if (isinstance<array>(new_array)) {
*this = std::move(new_array);
}
}
I have also created a test to trigger this case (only in resample
) and it looks like it works.
I have checked also that the copy does not happen by comparing the value of the pointer to the buffer before and after resize (looks like they are the same).
Is there a more principled way of doing that ?
@tuxu Did you have time to take a look at this? Is anything holding us back from merging and making a release? |
I verified that this refactor works on my M1 MacBook Pro, both x86_64 and arm64 versions of Python 3.12. @tuxu, it would be awesome if this fix could be merged and published when you have time! Thanks for all your work on this. |
@fakufaku @ideoforms Really sorry for the delay. Nothing holding us back from merging. I'll try to get this done today. |
Thanks, @fakufaku for the great work! The new release is live: https://pypi.org/project/samplerate/0.2.0/#files |
Woot 🎉 Thank you for the help and feedback on the code! Happy I could help! |
I've just tested out the pypi-published version 0.2.0 on a couple of laptops here. Python 3.9 on Intel macOS Sonoma Python 3.11 on Intel macOS Sonoma Python 3.9 on Apple M1 macOS Ventura Python 3.11 on Apple M1 macOS Ventura
I downloaded the wheel manually, and confirmed that, indeed, the .so in the "universal" wheel isn't really universal, but only contains an x86_64 slice.
@tuxu Maybe this is an issue with GitHub Actions' build for Mac arm64? |
@ideoforms Thanks for the feedback, and you're correct, the universal wheels are sadly broken for arm64. I guess this happens when CMake is called from Python. Will have a look. The GitHub runners are x86_64, so arm64 needs cross compilation. |
If you need an M1 runner I can recommend flyCI, they provide a pretty good amount of CI time for OSS projects for free. (Not affiliated, I just use them with LedFx to test on apple silicon, we use sample rate for audio processing) |
@shauneccles Thanks for the tip! I'll check that out. Running tests on arm64 would be nice to have. @ideoforms Meanwhile I found the problem with the |
This PR replaces the CFFI bindings that require a local copy of the dynamic libsamplerate library by pybind11 bindings that are compiled statically with the libsamplerate library.
Together with github actions this allows to easily create binary wheels for a range of python versions on macOS and windows. For Linux and other architectures, all that is required is a C++14 compiler to be available and pip can then compile the wheel locally.
original discussion
proof of concept can be installed from pypi
Pros
Cons
Changes compared to current version
channels
andconverter_type
to theCallbackResampler
class so that it mirrorsResampler
(n_samples,)
and(n_samples, 1)
can be used interchangeably. This is very useful to have a uniform interface for any number of channels.TODO
does it make sense to spend energy to fix it?I removed it from the github action.