ATLAS3.9.79 now works with MinGW

2012-06-13
2013-01-09
  • R. Clint Whaley

    R. Clint Whaley - 2012-06-13

    Guys,

    I have released 3.9.79. It completes the Windows/MinGW work by allowing
    32-bit builds to be built using MinGW (3.9.78 allowed 64-bit MinGW builds).
    Please read pages 29-30 of the ATLAS installation guide
    (ATLAS/doc/atlas_install.pdf) for details on how to install in this fashion.

    I have rewritten the parallel framework to use native Windows threads rather
    than pthreads.  I believe that when built with MinGW, that the resulting libs
    should not depend in any way on cygwin anymore.  I.e., you need cygwin in
    order to build the ATLAS libs, but not to link and use the MinGW-atlas libs.
    I believe that MinGW is interoperable with both MSVC++ and Intel's compilers.
    If the above is true, then I think Windows support is complete for stable.
    I need someone who actually uses Windows do the following:
    (1) Build ATLAS on windows using MinGW as described in the install guide.
    (2) Try to link to the resulting libraries using a windows application
        built with a native compiler like MSVC++ or Intel compilers
    (3) Let me know what ISA you used (32- or 64-bit), and what compilers.

    If you use 32-bit MinGW, then the install shouldn't take long on most
    machines, since Windows can utilize the standard architectural defaults.
    For a 64-bit build, the ATLAS install will take O(day), since you can't
    use the ATLAS architectural defaults (see install guide for details).
    I have created win64 archdefs for one of the two win64 platforms I have
    access to (Core264SSE3), and it can be downloaded at:
       http://www.cs.utsa.edu/~whaley/ATL310/win64_archdef.tar

    Presently this file contains archdefs only for Core264SSE3, but if other
    Windows users get successful installs, and will send me their archdefs,
    we can build it up so that Windows64 users don't have to wait forever
    to install ATLAS.  See:
       http://math-atlas.sourceforge.net/devel/atlas_devel/atlas_devel.html#SECTION00070000000000000000
    for details on how to build your own archdefs.

    Please let me know if you are willing to help with any of the above!

    Thanks,
    Clint

     
  • Saurabh Garg

    Saurabh Garg - 2012-06-16

    Dear Clint,

    Thanks a lot for the windows support. I have managed to build 32-bit atlas on notebook running 64-bit Windows 7 using cygwin.  I started with fresh installation of cygwin and added gcc 4.5.3-3, mingw64-i686, and mingw64-x86_64.

    ========================================
    make configure work fine with following parameters:

    ${ATLAS_SRC_DIR}/configure -Si cputhrchk 0 -with-netlib-lapack-tarfile=/home/Saurabh/Atlas/Installer/lapack-3.4.1.tgz -force-tids="4 0 2 4 6" -shared -D c -DPentiumCPS=2000 -b 32 -Si nocygwin 1 -prefix=${ATLAS_INSTALL_DIR}

    ========================================
    make build builds libatlas.a and others but I got following error while building windows dll:

    make: Entering directory `/cygdrive/c/cygwin/home/Saurabh/Atlas/Win32_Core-i7_SSE3/lib'
    /cygdrive/c/cygwin/home/Saurabh/Atlas/Win32_Core-i7_SSE3/mgwgcc -fomit-frame-pointer -mfpmath=sse -O2 -fno-schedule-insns2 -msse3 -m32  -mstackrealign -mstackrealign -m32 -shared -o libtatlas.dll -Wl,"rpath-link /home/Saurabh/Atlas/Install/lib" \
               -Wl,-whole-archive libptlapack.a libptf77blas.a libptcblas.a libatlas.a -Wl,-no-whole-archive -L -lgfortran -lgcc -lc -lkernel32 -lm -lgcc
    i686-w64-mingw32-gcc-4.5.3: /home/Saurabh/Atlas/Install/lib: No such file or directory

    I managed to fix it by removing -Wl,"rpath-link /home/Saurabh/Atlas/Install/lib" from the bldDir/lib/Makefile. Then, I got bunch of undefined Fortran references which can be fixed by adding -llibgfortran. Finally I got errors about -lc not found and I fixed them by simply removing it. After these fixed and running make build again I got the following files in bldDir/lib:
    libatlas.a
    libcblas.a
    libf77blas.a
    libf77refblas.a
    liblapack.a
    libptcblas.a
    libptf77blas.a
    libptlapack.a
    libtstatlas.a
    libsatlas.dll
    libtatlas.dll

    So now I have dlls but to use them in VC++ I also need import libraries. I did this as follows:
    i686-w64-mingw32-gcc -shared -shared-libgcc -o atlas_3.9.79.dll -Wl,-output-def,atlas_3.9.79.def -Wl,-whole-archive libptlapack.a libptf77blas.a libptcblas.a libatlas.a -Wl,-no-whole-archive -lgfortran

    i686-w64-mingw32-gcc -shared -shared-libgcc -o atlas_3.9.79.dll -Wl,-output-def,atlas_3.9.79.def -Wl,-whole-archive liblapack.a libf77blas.a libcblas.a libatlas.a -Wl,-no-whole-archive -lgfortran

    This will create both DLL and DEF files. The DEF file can be converted to lib usable by VC++ using following command from VC++ command prompt: lib /nologo /MACHINE:x86 /def:atlas_3.9.79.def.

    I have test the dll and lib from above using a simple VC++ test consisting of cblas_daxpy. I will integrate atlas with GSL later run more comprehensive tests later.

    make build took about 10 hours on my machine. I have Core i7 quad core processor.

    ========================================
    make check didnt reported any errors.

    ========================================
    make time did reported any reference time so I guess there are no architectural defaults for Core i7. Timings are as follows:
    Clock rate=1995Mhz
                   single precision        double precision
                *********************    ********************
                   real      complex       real      complex
    Benchmark   %   Clock   %   Clock   %   Clock   %   Clock
    =========   =========   =========   =========   =========
      kSelMM       984.0      983.4      541.7      529.0
      kGenMM       276.1      273.1      276.5      261.1
      kMM_NT       266.8      261.8      263.1      260.3
      kMM_TN       274.7      268.9      257.5      255.1
      BIG_MM       938.1      950.4      518.9      516.6
       kMV_N       224.3      469.5      142.6      221.0
       kMV_T       207.4      253.3      142.4      213.6
        kGER       207.3      247.7      170.9      225.1

    Again thanks for all the hard work.

    Regards,
    Saurabh

     
  • Saurabh Garg

    Saurabh Garg - 2012-06-16

    Sorry for few typos but I guess I cant edit my post. At the end it should be:
    make time *didnt* reported any reference time…

     
  • R. Clint Whaley

    R. Clint Whaley - 2012-06-22

    Saurabh,

    Thank you very much for posting what you did to get things working!  This should help other Windows folks, as well as pointing out to me that I should try to build dynamic libs.  However, here are some comments to improve your builds:

    First, *never* throw this flag:
       -Si cputhrchk 0
    It's translation is: rather than optimized, I'd like my ATLAS to be randomly transformed.  I will remove this flag for the next release: I have never heard of it being used correctly, and everybody seems to be using it without realizing that it makes ATLAS almost useless as an optimizer.

    Second, why are you doing:
       -force-tids="4 0 2 4 6"
    This would make it so ATLAS is always spawning two threads to coreID=4, which would make it essentially half the speed of the other cores??

    >i686-w64-mingw32-gcc-4.5.3: /home/Saurabh/Atlas/Install/lib: No such file or directory
    Doesn't this mean that this is your ${ATLAS_INSTALL_DIR}, and that it needs to exist?

    >make time *didnt* reported any reference time…
    That means that ATLAS didn't use the archdefs, which is also why the install took 10hrs!  If you really have a Corei7, then ATLAS *does* have archdefs for that arch, and probably ATLAS failed to detect it for some reason.  If you want to open up a support tracker item as discussed:
       http://math-atlas.sourceforge.net/faq.html#help
    We might be able to track down what went wrong.

    Cheers,
    Clint

     
  • Saurabh Garg

    Saurabh Garg - 2012-06-24

    Dear Clint,

    Thanks for useful pointers.

    I agree about -Si cputhrchk 0. After reading documentation I realized I was not using it properly :-)

    Well according to documentation the format for tids is -force-tids="# <thread ID list>". So I figured the first number is the number of thread, followed by the thread ids. Even the examples follow the same format.

    Regarding "No such file or directory" error, yes I thought that path doesn't exists but even after creating the install directory with include and lib sub-directories I got this error. I did googled but couldn't find good explanation of this error.

    I will try once more to build the atlas and see if I can get it to use archdefs, if it fails then I will open a support tracker.

    Regards,
    Saurabh

     
  • R. Clint Whaley

    R. Clint Whaley - 2012-06-27

    Yes, I misread your tids spec, sorry for the confusion, I think it is OK.

     
  • R. Clint Whaley

    R. Clint Whaley - 2012-06-29

    Thank you very much for all the help!  Can I ask you to test something for me yet again?

    I believe that ATLAS 3.9.81 will now build all the .dll libs correctly if you just throw -shared.  Can you confirm that this is true?

    I do not have it make them VC-compatible as you describe, since I don't really understand that step.  If the .dlls are correctly built for you, can you post again the steps necessary to take those files and make VC-usable libs?  I am thinking to add an errata entry with your commands to help other VC users.

    Many many thanks,
    Clint

     
  • Saurabh Garg

    Saurabh Garg - 2012-06-29

    Sure I will build 3.9.81 but can we fix atlas not using archdefs for my machine, otherwise it just takes too long for atlas to build.

    Regards,
    Saurabh

     
  • R. Clint Whaley

    R. Clint Whaley - 2012-06-30

    Saurabh,

    Easiest thing is just to use the archdefs that you yourself generated.  In your original install.  Follow these directions to be build the archdefs:
       http://math-atlas.sourceforge.net/devel/atlas_devel/atlas_devel.html#SECTION00070000000000000000

    I believe you installed 3.9.79, in which case your archdefs will be gzipped, so gunzip them and then bzip2 them (so they end with ".tar.bz2").  I switched the newest ATLAS from gzip to bzip2 for all compression.

    Now, when you install, add the flag
      -Ss ADdir /path/to/dir/with/your.tar.bz2
    and ATLAS should use your archdefs rather than its default ones.

    Let me know if you have questions.

    thanks,
    Clint

     
  • Saurabh Garg

    Saurabh Garg - 2012-07-05

    Dear Clint,

    I can confirm that the Atlas 3.9.83 can build windows dll's flawlessly. Everything went smoothly.

    The configure command used was:
    ${ATLAS_SRC_DIR}/configure -b 32 -Si nocygwin 1 -shared -D c -DPentiumCPS=2000 -force-tids="4 0 2 4 6" -prefix=${ATLAS_INSTALL_DIR} -with-netlib-lapack-tarfile=/home/Saurabh/Atlas/Installer/lapack-3.4.1.tgz

    Then make build produces libsatlas.dll and libtatlas.dll in the lib directory. As I said before these DLL's alone cannot be used with MSVC++ without import libraries (with extension lib). I will update with you instruction to build import libraries in couple of days.

    Regards,
    Saurabh

     
  • Saurabh Garg

    Saurabh Garg - 2012-07-05

    Dear Clint,

    Using archdefs from previous build is a great feature. I can now build atlas in only 40 mins as compared to 11 hours previously :-)

    In order to build DLL's suitable for MSVC++ we need import libraries (lib files) but mingw cannot create these files directly. However, mingw can create def files which can be converted to lib file using lib tool provided by MSVC++.

    To build the def file for each atlas DLL we need to use -Wl,-output-def,def_file_name.def when compiling DLL from atlas *.a files. So I modified makes/Make.lib by adding a variable outdef to GCCTRY, and GCCTRY_norp and modifying other parts of makefile as necessary. Patch file is at the end of this post.

    This will produce libsatlas.dll, libsatlas.def,  libtatlas.dll, and libtatlas.def.
    And the vc++ import libraries can be then created by using:
    lib /nologo /MACHINE:x86 /def:libsatlas.def
    lib /nologo /MACHINE:x86 /def:libtatlas.def

    -- Make-Orig.lib 2012-07-04 20:31:48.000000000 +0800
    +++ Make-Mod.lib 2012-07-05 19:57:11.663842200 +0800
    @@ -50,60 +50,60 @@
                -whole-archive $(libas) -no-whole-archive $(LIBS)
    GCCTRY:
    $(GOODGCC) -shared -o $(outso) -Wl,"rpath-link $(LIBINSTdir)" \
    -           -Wl,-whole-archive $(libas) -Wl,-no-whole-archive $(LIBS)
    +           -Wl,-whole-archive $(libas) -Wl,-output-def,$(outdef) -Wl,-no-whole-archive $(LIBS)
    GCCTRY_norp:
    $(GOODGCC) -shared -o $(outso) \
    -           -Wl,-whole-archive $(libas) -Wl,-no-whole-archive $(LIBS)
    +           -Wl,-whole-archive $(libas) -Wl,-output-def,$(outdef) -Wl,-no-whole-archive $(LIBS)
    #
    # TRYALL is going to just try a bunch of library combinations that may work
    # on gnu platforms, hopefully one does.  It also tests doing the link by
    # LD or gcc; some places don't use the gnu LD command, but gcc may still work
    #
    TRYALL :
    - if $(MAKE) GCCTRY outso="$(outso)" libas="$(libas)" \
    + if $(MAKE) GCCTRY outso="$(outso)" outdef="$(outdef)" libas="$(libas)" \
             LIBS="$(F77SYSLIB) -lc $(LIBS) -lgcc" LIBINSTdir="$(LIBINSTdir)"; then \
                echo "$(outso) built wt gcc and all libs" ; \
    -        elif $(MAKE) LDTRY outso="$(outso)" libas="$(libas)" \
    +        elif $(MAKE) LDTRY outso="$(outso)" outdef="$(outdef)" libas="$(libas)" \
             LIBS="$(F77SYSLIB) -lc $(LIBS) -lgcc" LIBINSTdir="$(LIBINSTdir)"; then \
                echo "$(outso) built wt ld and all sys libs" ; \
    - elif $(MAKE) GCCTRY_norp outso="$(outso)" libas="$(libas)" \
    + elif $(MAKE) GCCTRY_norp outso="$(outso)" outdef="$(outdef)" libas="$(libas)" \
             LIBS="$(F77SYSLIB) -lc $(LIBS) -lgcc" LIBINSTdir="$(LIBINSTdir)"; then \
                echo "$(outso) built wt gcc and all libs and no rpath" ; \
    -        elif $(MAKE) GCCTRY outso="$(outso)" libas="$(libas)" \
    +        elif $(MAKE) GCCTRY outso="$(outso)" outdef="$(outdef)" libas="$(libas)" \
             LIBS="-lc $(LIBS) -lgcc" LIBINSTdir="$(LIBINSTdir)"; then \
                echo "$(outso) built wt gcc and all C libs" ; \
    -        elif $(MAKE) LDTRY outso="$(outso)" libas="$(libas)" \
    +        elif $(MAKE) LDTRY outso="$(outso)" outdef="$(outdef)" libas="$(libas)" \
             LIBS="-lc $(LIBS) -lgcc" LIBINSTdir="$(LIBINSTdir)"; then \
                echo "$(outso) built wt ld and -lc -lgcc" ; \
    -        elif $(MAKE) GCCTRY_norp outso="$(outso)" libas="$(libas)" \
    +        elif $(MAKE) GCCTRY_norp outso="$(outso)" outdef="$(outdef)" libas="$(libas)" \
             LIBS="-lc $(LIBS) -lgcc" LIBINSTdir="$(LIBINSTdir)"; then \
                echo "$(outso) built wt gcc and all C libs and no rpath" ; \
    -        elif $(MAKE) GCCTRY outso="$(outso)" libas="$(libas)" \
    +        elif $(MAKE) GCCTRY outso="$(outso)" outdef="$(outdef)" libas="$(libas)" \
             LIBS="$(F77SYSLIB) -lc $(LIBS)" LIBINSTdir="$(LIBINSTdir)"; then \
                echo "$(outso) built wt gcc and all libs except -lgcc" ; \
    -        elif $(MAKE) LDTRY outso="$(outso)" libas="$(libas)" \
    +        elif $(MAKE) LDTRY outso="$(outso)" outdef="$(outdef)" libas="$(libas)" \
             LIBS="$(F77SYSLIB) -lc $(LIBS)" LIBINSTdir="$(LIBINSTdir)"; then \
                echo "$(outso) built wt all libs except -lgcc" ; \
    -        elif $(MAKE) GCCTRY_norp outso="$(outso)" libas="$(libas)" \
    +        elif $(MAKE) GCCTRY_norp outso="$(outso)" outdef="$(outdef)" libas="$(libas)" \
             LIBS="$(F77SYSLIB) -lc $(LIBS)" LIBINSTdir="$(LIBINSTdir)"; then \
                echo "$(outso) built wt gcc and all libs except -lgcc, no rpath" ; \
    -        elif $(MAKE) GCCTRY outso="$(outso)" libas="$(libas)" \
    +        elif $(MAKE) GCCTRY outso="$(outso)" outdef="$(outdef)" libas="$(libas)" \
             LIBS="-lc $(LIBS)" LIBINSTdir="$(LIBINSTdir)"; then \
                echo "$(outso) built wt gcc and -lc" ; \
    -        elif $(MAKE) LDTRY outso="$(outso)" libas="$(libas)" \
    +        elif $(MAKE) LDTRY outso="$(outso)" outdef="$(outdef)" libas="$(libas)" \
             LIBS="-lc $(LIBS)" LIBINSTdir="$(LIBINSTdir)"; then \
                echo "$(outso) built wt ld and -lc" ; \
    -        elif $(MAKE) GCCTRY_norp outso="$(outso)" libas="$(libas)" \
    +        elif $(MAKE) GCCTRY_norp outso="$(outso)" outdef="$(outdef)" libas="$(libas)" \
             LIBS="-lc $(LIBS)" LIBINSTdir="$(LIBINSTdir)"; then \
                echo "$(outso) built wt gcc and -lc, no rpath" ; \
    -        elif $(MAKE) LDTRY outso="$(outso)" libas="$(libas)" \
    +        elif $(MAKE) LDTRY outso="$(outso)" outdef="$(outdef)" libas="$(libas)" \
             LIBS="$(LIBS)" LIBINSTdir="$(LIBINSTdir)"; then \
                echo "$(outso) built wt ld" ; \
    -        elif $(MAKE) GCCTRY_norp outso="$(outso)" libas="$(libas)" \
    +        elif $(MAKE) GCCTRY_norp outso="$(outso)" outdef="$(outdef)" libas="$(libas)" \
             LIBS="$(F77SYSLIB) -lkernel32" LIBINSTdir="$(LIBINSTdir)"; then \
                echo "$(outso) built wt fortran and kernel32, no rpath" ; \
             else \
    -           $(MAKE) GCCTRY outso="$(outso)" libas="$(libas)" \
    +           $(MAKE) GCCTRY outso="$(outso)" outdef="$(outdef)" libas="$(libas)" \
                LIBS="$(LIBS)" LIBINSTdir="$(LIBINSTdir)" ; \
             fi

    @@ -152,19 +152,23 @@
    ptdlls: tdlls
    tdlls:                          # threaded target
    $(MAKE) TRYALL outso=libtatlas.dll \
    +             outdef=libtatlas.def \
                     libas="libptlapack.a libptf77blas.a libptcblas.a libatlas.a" \
                     LIBINSTdir="$(LIBINSTdir)"
    sdlls:                          # serial target
    $(MAKE) TRYALL outso=libsatlas.dll \
    +             outdef=libsatlas.def \
                     libas="liblapack.a libf77blas.a libcblas.a libatlas.a" \
                     LIBINSTdir="$(LIBINSTdir)"
    cdlls: ctdlls csdlls
    ctdlls: libptclapack.a          # threaded target
    $(MAKE) TRYALL outso=libtatlas.dll \
    +             outdef=libtatlas.def \
                     libas="libptclapack.a libptcblas.a libatlas.a" \
                     LIBINSTdir="$(LIBINSTdir)"
    csdlls: libclapack.a            # serial target
    $(MAKE) TRYALL outso=libsatlas.dll \
    +             outdef=libsatlas.def \
                     libas="libclapack.a libcblas.a libatlas.a" \
                     LIBINSTdir="$(LIBINSTdir)"

     
  • R. Clint Whaley

    R. Clint Whaley - 2012-07-10

    Saurabh,

    I have added a special cases for everything you outline above, and have confirmed that on my Windows I can build a .lib.  However, I don't use MSCV++, so I can't confirm that the resulting .lib is actually good.

    Can you install atlas3.9.87, and tell me if you can create usuable .lib files from them for MSVC++?  I am hoping to release the stable tomorrow.

    Speaking of which, I have added the following lines to the ATLAS/doc/AtlasCredits.txt file:
                                    Saurabh Garg
           ** Help with building MSVC++ compatible shared libraries.  See:
              https://sf.net/projects/math-atlas/forums/forum/1026734/topic/5349864

    Is there anything I should correct or add (maybe an affiliation?).

    Thanks again for helping with this.  Since I don't use shared libs, much less Windows .libs, without folks like you to help, I couldn't get this stuff to work in ATLAS!

    Thanks,
    Clint

     
  • Saurabh Garg

    Saurabh Garg - 2012-07-11

    Yes atlas3.9.87 builds just fine and I was able to use the resulting lib with VC++. I think you should copy def files along with dlls on make install.

    Thanks!! It's just fine, I don't want to put an affiliation.

    Regards,
    Saurabh

     

Log in to post a comment.