tmcdonell / cuda

Haskell FFI bindings to CUDA
Other
76 stars 36 forks source link

Support for Windows — replacing autoconf with Setup.hs #30

Closed mwu-tow closed 9 years ago

mwu-tow commented 9 years ago

Summary of changes

Removed the dependency on autotools that causes problems on Windows (as discussed in #25). The functionality from configure.ac (detecting CUDA Toolkit and passing additional flags to ghc) was implemented in Setup.hs. User can now override results of Setup.hs configure step by providing custom cuda.buildinfo file.

Thanks to that, the package neatly installs on Windows machines with CUDA without requiring additional dependencies, special environment nor restricting the possible CUDA locations (paths with spaces just work).

The package should install as before on Linux and OSX machines, though some more testing (particularly on OSX) would be welcome.

Because the extraGHCiLibs support was introduced in Cabal 1.22, that version is needed to compile the package.

Changes in detail

What's changed

Old behaviour:

Setup.hs executed the configure script that yielded cuda.buildinfo file (being essentially a map of flags). Setup.hs used then that file to perform build.

New behaviour:

Setup.hs looks for CUDA Toolkit and based upon its location and current platform generates file cuda.buildinfo.generated. Then, as before, the file is used when performing build.

In case when something goes wrong (or just to ease experimenting) user can provide a custom cuda.buildinfo file. If it is present, it will be prefered over the generated one.

Other differences

I removed options for C2HS that set nvcc as the C preprocessor. It is impossible to use it on Windows, however using MinGW's gcc seems to work just fine. If it works on Windows, all the more it should work on Linux. So to avoid unnecessery differences between platforms, I've removed nvcc from its role as preprocessor for C2HS everywhere.

Even though I tried to provide all the needed logic in Setup.hs it is not necessarily the same as the old configure.ac. For example, it does not check whether cuda and cudart actually do export functions we expect. Implementing this in Haskell seemed troublesome and I didn't think it is worth of benefit. I'd say it is rather the Cabal library that should provide such methods as part of their configuration utilities.

I was forced to bump the required cabal library to 1.22 due to extra-ghci-libraries support being added in that version. This option is needed on Windows to avoid the need to rename the CUDA Toolkit dlls (as they don't match filenames of their respective .lib import libraries). I believe it should be possible to work around this requirement, yet it was not worth the effort needed.

How does it work

CUDA Toolkit detection iterates over candidate locations and takes the first one looking like CUDA Toolkit. The candidate locations are currently:

The location is considered valid when it contains include/cuda.h file. In future that validation rule may be refined. When CUDA Toolkit cannot be find, configure step fails. Setup.hs outputs the checked locations and reason why were they rejected, so it should be pretty obvious what is going on.

Flags added on all patforms:

Windows-only flags:

OSX-only flags

I tried to follow the behaviour of configure.ac. However, as I observed, some of the flags that are set, are not needed for me to compile:

I have done tests on computers in my company. They likely have CUDA installed in an uniform way, so help in testing in different environment would be welcome. On Windows machines my version works. On Linux machines both old and proposed version of setup work. On a single Mac machine with CUDA I was able to obtain, neither did work — it needed to be run with /usr/local/cuda/lib being passed as --extra-lib-dirs. When it is passed, both current and my version work.

In my tests on OSX I haven't observed any difference whether framework is defined or not along with is path -F/Library/Frameworks. I have left it, as I have no idea why it was needed but I'd be happy to know whether it can be safely removed or not.

To sum up: my version works on all machines when current configure.ac worked. It additionally works on Windows. I'd be great to have it tested in other environment — if there are any issues with the new Setup.hs I'd be happy to fix them, or provide you needed help.

tmcdonell commented 9 years ago

This is great!! Thanks for the very comprehensive summary of changes as well. I'll test this out on a Mac or two here as you suggest, but otherwise it looks like you have tested pretty well already and it looks fine.

mwu-tow commented 9 years ago

I pushed a few more commits based on Travis outputs. I got the checks to pass by updating cabal and cabal-install. The only one failing is the GHC-head one (that cannot update cabal-install) — I'm not sure how to fix it, but it was failing anyway so I'll leave it for later.

That'd be all from my side, I have no plans for further changes now — unless new issues are found.

tmcdonell commented 9 years ago

Out of curiosity... I noticed that you had a separate 'windows' branch which shows the development history. I would have been happy to accept the pull request directly from there (preferred, even). Any reason you chose to squash the commits? (maybe these branches are actually different attempts, I didn't look in detail.)

mwu-tow commented 9 years ago

Indeed, this branch was squashed version of windows. I did it because the windows is full "dirty" commits that I made to track my development, not because they make sense. Some had intentional errors to check the error handling, there were some experiments appearing and disappearing, as I tweaked things, looking for the most satisfactory solution. Practically all commits there are broken in one way or another (i.e. don't work on some platforms) and I didn't see reason why anyone would want to return to them. Well, perhaps git-blaming the Setup.hs for rationale… But all the needed info is in the comments anyway I think. (Still, I could've replaced this squashed version with original branch history if you'd say so.)

tmcdonell commented 9 years ago

No it's fine, I was just curious and thought I would ask. I guess it makes sense to squash it as you did since they are mostly work-in-progress commits, but I wouldn't have minded.

I have merged the changes. I will upload the new version to Hackage shortly.

Thanks again for this monumental effort! Really great work!!