-
Notifications
You must be signed in to change notification settings - Fork 52
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Remove dependency on bindgen #28
Comments
Hi there! I understand your concerns about having Your observations as to why
and
I rarely get around to working on An acceptable contribution should – I think – contain at least the following:
If this list of requirements makes this task too daunting, I completely understand, I already admitted that I am also not willing to work on this (at least for now). However I feel like anything less would only make this a brittle work-around. If you do still want to work on it, go for it! Something that could make this task easier is this initiative by the MPICH project which aims to offer a somewhat stable ABI across certain versions of MPICH and various other MPI libraries based on it http://www.mpich.org/abi/. However, the information on that page seems to be a bit stale. Similar information for Open MPI can be found here https://www.open-mpi.org/software/ompi/versions/. |
Thank you for the quick answer!
Yes, this is how I see this implemented too.
I feel like this would be the hardest part. I don't really know that much about MPI, so I guess the following would be relevant:
I don't see rustc version relevant here, the FFI will always work the same due to backward compatibility requirements. But as we are talking about C software here, maybe the C compiler used will have an influence? Or some compiler flags maybe too (like how in fortran you can specify the default size of integer at the command line)? Or is this all abstracted by
This should be as easy as copying the generated file and adding some lines in build.rs to emit the corresponding
I did not knew about this, this is very nice! Does this mean that all the listed implementation on the MPICH page are ABI compatible? And maybe the compatibility extends to the following compatible releases (for some definition of compatible ^^) |
I agree this is probably the largest chunk of work. It is not really about MPI though. None of this is specified by the standard.
Yes, note that MPI version here means MPI library version (as in Open MPI 1.10.0) not the version of the MPI standard.
Yeah, I am pretty sure that it is not of concern at the moment. I do think
Your guess is as good as mine. I would say if the headers of an MPI library built with two different C compilers are the same than the compiler does not matter. One other thing I just thought of: it might not be legal to distribute pre-generated FFI declarations that are based on header files of some of the commercial MPI libraries. E.g. the |
I did not thought of this =/ Yeah, it might be hard to distributed some of the bindings. For Intel MPI specifically, it looks like it is based on MPICH, so we might get around the issue by using the same bindings for MPICH and Intel. But maybe rust-lang/rust-bindgen#918 is a better solution to this problem. Bundling libclang would make most of my initial problems go away. I'll try to investigate both solutions. |
There has been no movement here or over in the |
I've got an idea for a perhaps more tractible solution to this problem. We could add some tool that generates a vendored version of mpi-sys (as a tar ball or something like that). Then the user can use the The benefits of this are:
Downsides:
[0] Produced using |
This should work but I am not sure this is the best solution.
This is a bit of a bummer, because the idea was to completely get rid of the hard to install libclang. Plus pushing management of mpi-sys on the user is less than ideal if you want to have users who are nor rust developers. |
Just though of another possible fix for the problem here: shipping an implementation of MPI (possibly MPICH/OpenMPI) with rsmpi itself. This would be under an optional feature, and the MPI implementation would be compiled before compiling rsmpi. This means that we can control and ship the bindgen output for this particular, blessed implementation of MPI. I am not sure if this could work, or if I am just showing my complete lack of understanding of MPI, but it look like one can install and use it's own MPI implementation on a cluster, without relying on the one provided with the cluster. What do you think? |
Well, shipping an open source implementation of MPI with the
I will try to do some experiments regarding the first point by installing Open MPI or MPICH an different platforms and seeing whether the resulting |
For student cluster competitions we always build OpenMPI 3.0 from source because CentOS ships the ancient 1.x version (and the difference in performance is significant) On production clusters you often have to build your own version of compilers, etc. because admins don't want to put the newer version, even as a |
I have an other idea to fix the issue here. My understanding of the problem is that some MPI types use different ABI in different implementations, meaning that is it not possible to assume all mpi.h are equivalent. A possible way to work around this would be to provide a small shim around MPI functions where rsmpi would be in control of the ABI, which would call into the local MPI installation. Something like this #include <mpi.h>
#include <stdint.h>
// use types with known size to calling the functions from rust
typedef int32_t RSMPI_Comm;
typedef int32_t RSMPI_Group;
int RSMPI_Comm_create(RSMPI_Comm comm, RSMPI_Group group, RSMPI_Comm *newcomm) {
MPI_Comm new;
int status = MPI_Comm_create((MPI_Comm)(comm), (MPI_Group)(group), &new);
*newcomm = (RSMPI_Comm)(new);
return status;
}
// and so on for everything used by rsmpi Then, this file would be compiled with user-provided The main drawback I can see with this approach are
What do you think? |
I think there's some merit to the idea - I've thought about doing this in the past. A couple things:
Though a possibility could be that you compile and run a program as part of |
This is another alternative, and how the Julia bindings to MPI do it. You may also want to get the alignment of the types right. I don't know how one would create a fully opaque type with given size and alignment in safe rust though. |
I think it's more appropriate for a wrapper layer to live outside rsmpi. This project, for example, has been around for a while, but is now nicely licensed. At this point, I think avoiding bindgen has nontrivial maintenance costs and a specialized |
Hi !
I would love to use this crate in my application, but I have a single issue with it, which is that the ffi bindings are generated at compile time for the specific mpi implementation used by using bindgen.
While I like bindgen, it has a lot of issues, especially when using it at compile time: the final user needs to have libclang installed, at the right version and at the right place to be sure that code generation works.
I think this can be a big hurdle when trying to use this crate. Here are a few examples:
Why is bindgen used
This is my understanding of why bindgen is used at compile time in this crate, please correct me if I am wrong!
MPI does not have any stable ABI, only a specification and a C API. This crate uses a small C shim to ensure
#define
d symbols are available to Rust, and bindgen to parse the mpi headers and then generate corresponding ffi declaration for Rust.Removing bindgen dependency
I think it could be possible to remove bindgen dependency at build time by pre-generating the FFI declaration for all the different MPI implementations and versions, and then detecting which one to use in
build.rs
by parsing the output ofmpicc
.Of course generating the declaration for every single implementation and every single version is not going to be practical, and thus one could generate the declaration for some implementation/versions couples (starting with the latest release of OpenMPI and MPICH for example), and then defaulting to use bindgen for all the others cases.This would keep the benefits of having an easy way to use this crate, even with exotic MPI implementation, while having smaller build time and simpler build for 80% of the cases.
Please tell me what you think of this! Is there something I overlooked?
If you agree with this proposal, I could try to implement it, I have some experience with bindgen and Rust FFI.
The text was updated successfully, but these errors were encountered: