As a result of my previous post, I’ve had a number of requests to describe how I compiled the BLAS, so I’ll do so below. Of course, the necessary caveats, I am not a programmer nor do I play one on the radio so I probably cannot debug any issue anyone may have. Use the BLAS at your own risk and reward. If you use it win the Nobel prize, the credit is all yours (and that of R-core and the OpenBLAS team). If your computer explodes into a pile of slag, opening a dimensional portal to the netherworld and starting the zombie apocalypse, you’re on your own (although I’d appreciate a quick e-mail telling me to run for the hills). The instructions generally assume that you have some familiarity with compiling programs on Windows, especially versions of R. If not, it is crucial (and a good idea in any event) to read and understand the R Installation and Administration manual, especially the portions on compiling for Windows. Even though I have done so dozens of times over the past five years, I still keep the manual open when I am performing a new compilation.
Compiling OpenBLAS
- Obtain a decompressor which can handle 7z. I personally use Peazip.
- Download the OpenBLAS (hereafter referred to as OPB) source code. The version I used was v0.28
- Follow the directions at the OpenBLAS installation guide in selecting and downloading the appropriate MSYS and MINGW64 packages. I used:
- The rubenvb 64 bit x86_64-w64-mingw32-gcc-4.8.0-win64_rubenvb, which is GCC 4.8.0 for Win64 with a Win64 target.
- Version 13.7 of the suggested MSYS package.
- Expand the MINGW64 and MSYS compressed files.
- It probably makes sense to do this in a new subdirectory which will be referred to as OPB_HOME. Personally, I expanded them both into C:\OPB.
- Expand/unzip the OPenBLAS source code into OPB_HOME.
- Edit your path to remove all reference to Rtools\bin and Rtools\gcc-4.6.3\bin if there are any from previous compilation attempts and add the following line to the front of the path: “OPB_HOME\mingw64\bin;OPB_HOME\msys\bin;” where OPB_HOME is the path described above. In may case, it looked like C:\OPB\mingw64\bin;C:\OPB\msys\bin;
- Navigate to OPB_HOME\msys and run the msys.bat file; this creates the necessary home directories. Immediately exit the instance by typing exit
- Copy the expanded Openblas source code directory into the newly created OPB_HOME\msys\home\USER_NAME subdirectory.
- Copying instead of moving makes it a bit easier to restart if a new compilation is needed.
- Open the file Makefile.rule in the OPB source code directory with a text editor (I use Notepad++) and make the follow changes. Some of them require uncommenting, which means removing the # at the beginning of the line:
- Set FC = gfortran (Line 25 in v0.28)
- Set BINARY=64 (Line 35 in v0.28)
- Set USE_THREAD = 0 (Line 41 in v0.28). Multi-threaded BLASes may lead to improved results, but often don’t and can be the cause of other conflicts, I believe.
- Set NO_SHARED = 1 (Line 52 in v0.28)
- Set NO_LAPACK = 1 (Line 59 in v0.28)
- Set NO_PARALLEL_MAKE = 1 (Line 85 in v0.28). In my experience, the GCC-based compilers for Windows do not handle parallel makes well.
- Run the msys.bat file to open an instance of MSYS.
- Navigate to the directory in which the source code and makefiles sit, and type “make“
- After a while and lots of fast-scrolling text, the compilation should finish successfully. If it does not, and you followed all of the above steps, you’ll probably have a few tens of hours of online searching to do to try and figure out what went wrong, I’m afraid.
At this point, in the OPB folder within the MSYS install, there will be a file with the name libopenblas_sandybridge-r0.2.8 where sandybridge may be something different depending on your processor (nehalem, prescott, etc.). This is the compiled static BLAS which will be fed into the R compilation.
Compiling R
I am not going to go through an exhaustive step-by-step explanation of how to compile R, the manual does a much better job than I could. However, there are some steps that need to be taken to allow R to use the BLAS created above.
- Download and install the latest version of Rtools, including any additional files.
- During the install it is very important to allow Rtools to add its binaries to the PATH, and to delete the MSYS and MINGW entries from the PATH. Otherwise, there will be two versions of GCC related tools in the path, and mayhem may ensue.
- Expand the R source code into R_HOME as described in the manual, including any extra needed files such as the tcl, bitmap (tiff, jpeg, etc.), cairodevices
- I strongly recommend having a proper install of MIKTEX, Inno, and qpdf as described in the installation manual. Even if you are not interested in creating a full-fledged installer, creating it will help minimize the potential errors found in the checking stage, and thus will make it easier to see if the BLAS is causing a failure.
- Open R_HOME/src/gnuwin32/MkRules.dist and make the following changes, if necessary:
- Set USE_ATLAS=YES (Line 21 in 3.0.2)
- Set ATLAS_PATH (Line 22 in 3.0.2) to wherever you have the libopenblas file. For example, if you moved the static library to C:\R\BLAS then set ATLAS_PATH=C:/R/BLAS/. Note the forward slashes (/) instead of backslashes (\). This applies to any path in the makefile, such as cairo, Inno, and qpdf.
- Set MULTI = 64 (Line 31 in 3.0.2)
- Set WIN = 64 (Line 57 in 3.0.2)
- Set the appropriate paths for Cairo, Inno and qpdf as necessary
- I would recommend researching the particular machine for which you are compiling, and setting the EOPTS with the appropriate march or at least mtune flag. More information for Rtool‘s version’s GCC settings, see the entries in its documentation.
- Navigate to and open R_HOME\src\extra\blas\Makefile.win and change line 15 from:-L../../../$(IMPDIR) -lR -L"$(ATLAS_PATH)" -lf77blas -latlas to -L../../../$(IMPDIR) -lR -L"$(ATLAS_PATH)" -lopenblas-r0.2.8 where -lopenblas-r0.2.8 is the name of the .a file but starting with “-l” and not “lib”.
- Compile the base R by running make all. If there is a problem with the BLAS and/or its path, this process will fail.
- If the base R compiles properly, and there is an Rblas in R_HOME\bin\x64, then finish the compilation with the following steps (as appropriate):
- make bitmapdll
- make cairodevices
- make recommended
- make vignettes
- make manuals
- make rinstaller
- At this point, run make check-all, prefereably piping it into a text file (such as make check-all > CheckAll.txt). This can take upwards of 20 minutes. If there is an issue with the BLAS, the check will fail somewhere, although failing the internet check is not a problem. I pay careful attention to the times when the check is working on the base, stats, Matrix, and mgcv packages, as most of the time, failures occur in these routines.
- When completed, check the R_HOME\tests folder and any subdirectory for .Rout.fail files. If you created a log file, then search it for the word ERROR. Many of them will be fine (statements that errors have not been found or the internet failure) but a true error should be found if it exists.
If the check completes and there are no fail files, them congratulations! The Rblas.dll file in R_HOME\bin\x64 is a BLAS tuned to your specific machine.
If anyone does successfully complete this process, I would be very interested to know how much, if at all, the matrix/linear algebra have sped up. Good Luck!
Hello Avraham,
I was trying to build this, got through compiling openBLAS, which was a breeze and quite fast. But got stuck while compiling R. It went through byte compiling, but got stuck at grDevices compilation. Logs are at http://pastebin.com/hFjJvmQB. Would you have any idea to go past this error?
A breif google search shows that appears to be a memory-mapping issue. Did you build a single or multi-threaded BLAS, and did you build a 64 bit BLAS and try to map it to a 32 bit R or vica versa? Maybe that is the problem?
Hi Avraham, thanks for this interesting post. I followed your step-by-step instructions and I was able to correctly compile openBLAS for windows, but when I try to make all R, after a while, I receive errors 1 and 2:
gcc -std=gnu99 -I../include -I. -I../extra -DHAVE_CONFIG_H -DR_DLL_BUILD -c -o e_pow.o e_pow.S
e_pow.S: Assembler messages:
e_pow.S:110: Error: invalid instruction suffix for
pop'
pop’e_pow.S:111: Error: invalid instruction suffix for
e_pow.S:227: Error: invalid instruction suffix for
pop'
pop’e_pow.S:228: Error: invalid instruction suffix for
e_pow.S:278: Error: invalid instruction suffix for
pop'
pop’e_pow.S:279: Error: invalid instruction suffix for
e_pow.S:313: Error: invalid instruction suffix for
pop'
pop’e_pow.S:314: Error: invalid instruction suffix for
make[3]: *** [e_pow.o] Error 1
make[2]: *** [../../bin/i386/R.dll] Error 2
make[1]: *** [rbuild] Error 2
make: *** [all] Error 2
Any suggestion?
Thanks.
Sorry, I don’t immediately recognize those errors, but based on http://stackoverflow.com/questions/21679131/error-invalid-instruction-suffix-for-push, it seems as if you’re mixing 32bit and 64bit. Are you building 32bit R and trying to blend in a 64bit BLAS?