[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

atlas: FTBFS on hurd-i386 (for review)



Source: atlas
Version: 3.8.4-9
Severity: important
Tags: patch
Usertags: hurd
User: debian-hurd@lists.debian.org

Hello,

Attached are two patches to enable a successful build of atlas on
GNU/Hurd. The first,fix_build.patch, fixes the build problems for Hurd
by not using the compiler reserved keyword MACH as a variable. The
second, fix_hurd_support.patch, adds proper support for GNU/Hurd. It
uses x86info to estimate important CPU information, since /proc/cpuinfo
is not (yet) available.

The new backend file, archinfo_gnu.c, is an edited copy of the _linux
version, and should be trimmed to use only features available from
x86info. Feedback wanted, especially here. However, it looks like not
many of the features defined in that file are used for building atlas,
except for the CPU frequency (and maybe number of CPUs and threads).

Thanks!
--- CONFIG_src_probe_comp.c.orig	2012-09-04 16:05:39.000000000 +0200
+++ atlas-3.8.4/CONFIG/src/probe_comp.c	2012-09-09 10:48:55.000000000 +0200
@@ -221,11 +221,11 @@
    }
    return(0);
 }
-void NamesToBitField(int MACH, char *str, int *bits)
+void NamesToBitField(int TYPE, char *str, int *bits)
 /*
- * Takes a list of machine (MACH=1) or OS (MACH=0) names and translates them
- * to their enumerated type numbers, and sets the appropriate bit in the
- * bits field
+ * Takes a list of machine (TYPE=1) or OS (TYPE=0) names and
+ * translates them to their enumerated type numbers, and sets the
+ * appropriate bit in the bits field
  */
 {
    char name[128];
@@ -240,14 +240,14 @@
             i = 0;
          else
          {
-            if (MACH)
+            if (TYPE)
                i = MachNameToInt(name);
             else
                i = OSNameToInt(name);
             if (!i)
             {
                fprintf(stderr, "Nonsensical %s name in list: %s\n",
-                       MACH ? "machine" : "OS", str);
+                       TYPE ? "machine" : "OS", str);
                exit(1);
             }
          }
diff -urN atlas-3.8.4/CONFIG/include/atlconf.h atlas-3.8.4.patched/CONFIG/include/atlconf.h
--- atlas-3.8.4/CONFIG/include/atlconf.h	2012-09-06 23:26:20.000000000 +0200
+++ atlas-3.8.4.patched/CONFIG/include/atlconf.h	2012-09-05 16:44:29.000000000 +0200
@@ -6,12 +6,12 @@
 #include <string.h>
 #include <assert.h>
 
-#define NOS 12
+#define NOS 13
 static char *osnam[NOS] =
    {"UNKNOWN", "Linux", "SunOS", "SunOS4", "OSF1", "IRIX", "AIX",
-    "Win9x", "WinNT", "HPUX", "FreeBSD", "OSX"};
+    "Win9x", "WinNT", "HPUX", "FreeBSD", "OSX", "GNU"};
 enum OSTYPE {OSOther=0, OSLinux, OSSunOS, OSSunOS4, OSOSF1, OSIRIX, OSAIX,
-             OSWin9x, OSWinNT, OSHPUX, OSFreeBSD, OSOSX};
+             OSWin9x, OSWinNT, OSHPUX, OSFreeBSD, OSOSX, OSGNU};
 #define OSIsWin(OS_) (((OS_) == OSWinNT) || ((OS_) == OSWin9x))
 
 enum ARCHFAM {AFOther=0, AFPPC, AFSPARC, AFALPHA, AFX86, AFIA64, AFMIPS};
diff -urN atlas-3.8.4/CONFIG/src/backend/archinfo_gnu.c atlas-3.8.4.patched/CONFIG/src/backend/archinfo_gnu.c
--- atlas-3.8.4/CONFIG/src/backend/archinfo_gnu.c	1970-01-01 01:00:00.000000000 +0100
+++ atlas-3.8.4.patched/CONFIG/src/backend/archinfo_gnu.c	2012-09-06 16:30:09.000000000 +0200
@@ -0,0 +1,290 @@
+#include "atlconf.h"
+
+void PrintUsage(char *name, int i)
+{
+   fprintf(stderr, "USAGE: %s -v (verb) -b (@ bits) -a (arch) -n (ncpu) -c <ncache> -C <lvl> (cache size) -m (Mhz) -t (cpu throttling)\n", name);
+   exit(i);
+}
+
+int GetFlags(int nargs, char **args, int *CacheLevel)
+{
+   int i, flag = 0;
+
+   *CacheLevel = 0;
+   for (i=1; i < nargs; i++)
+   {
+      if (args[i][0] != '-') PrintUsage(args[0], i);
+      switch(args[i][1])
+      {
+      case 'n':
+         flag |= Pncpu;
+         break;
+      case 'c':
+         flag |= Pncache;
+         break;
+      case 'C':
+         if (++i > nargs)
+            PrintUsage(args[0], i);
+         *CacheLevel = atoi(args[i]);
+         break;
+      case 'v':
+         flag |= Pverb;
+         break;
+      case 'm':
+         flag |= PMhz;
+         break;
+      case 'a':
+         flag |= Parch;
+         break;
+      case 'b':
+         flag |= P64;
+         break;
+      case 't':
+         flag |= Pthrottle;
+         break;
+      default:
+         PrintUsage(args[0], i);
+      }
+   }
+   if (!flag)
+     flag = Parch | P64;
+   return(flag);
+}
+
+enum MACHTYPE ProbeArch()
+{
+   enum ARCHFAM fam;
+   enum MACHTYPE mach=MACHOther;
+   int ierr, i;
+   char res[1024];
+
+   fam = ProbeArchFam(NULL);
+   switch(fam)
+   {
+   case AFX86:
+      res[0] = '\0';
+      ierr = CmndOneLine(NULL, "x86info | grep 'CPU Model'", res);
+      if (ierr || res[0] == '\0')
+         ierr = CmndOneLine(NULL, "x86info | grep 'CPU Model'", res);
+      if (!ierr && res[0] != '\0')
+      {
+         if (strstr(res, "Pentium"))
+         { /* Pentium of some flavor */
+            if (strstr(res, " III ")) mach = IntPIII;
+            else if (strstr(res, " II ")) mach = IntPII;
+            else if (strstr(res, "Pro")) mach = IntPPRO;
+            else if (strstr(res, "MMX")) mach = IntP5MMX;
+            else if (strstr(res, " 4 "))
+            {
+               ierr = CmndOneLine(NULL,
+                      "x86info | grep 'Model' | grep -v 'CPU'", res);
+               if (!ierr)
+               {
+                  i = GetLastInt(res);
+                  if (i < 3) mach = IntP4;
+                  else if (i == 3) mach = IntP4E;
+               }
+            }
+         }
+         else if (strstr(res, "Core"))
+         {
+            if (strstr(res, "i7"))
+            {
+               if (strstr(res, "2600"))
+                  mach = IntCorei2;
+               else
+                  mach = IntCorei1;
+            }
+            if (strstr(res, "i5"))
+            {
+               if (strstr(res, "i5-2500") || strstr(res, "i5-2400") ||
+	           strstr(res, "i5-2390") || strstr(res, "i5-2300"))
+                  mach = IntCorei2;
+               else
+                  mach = IntCorei1;
+            }
+         }
+         else if (strstr(res, "Xeon")) /* dreaded Xeon-is-anything */
+         {
+            if (strstr(res, "E5420")) mach = IntCore2;
+         }
+         else if (strstr(res, "Efficeon")) mach = TMEff;
+         else if (strstr(res, "Athlon HX")) mach = AmdHammer;
+         else if (strstr(res, "Opteron") || strstr(res, "Hammer") ||
+                  strstr(res, "Athlon(tm) 64"))
+            mach = AmdHammer;
+         else if (strstr(res, "Athlon")) mach = AmdAthlon;
+         else if (strstr(res, "AMD-K7")) mach = AmdAthlon;
+      }
+      break;
+   }
+   return(mach);
+}
+
+int ProbeNCPU()
+{
+   int ncpu = 0;
+   char *reslns, res[1024];
+
+   #if 0
+   if (mach == Dec21264 || mach == Dec21164 || mach == Dec21064)
+   {
+     /* FIXME: GetFirstInt */
+      if ( !CmndOneLine(NULL, "x86info | grep 'processor' | grep -v 'threads'", res) )
+         ncpu = GetFirstInt(res);
+   }
+   #endif
+   /* FIXME
+   if (!ncpu)
+   {
+      reslns = CmndResults(NULL, "grep '^processor' /proc/cpuinfo");
+      if (reslns) ncpu = fNumLines(reslns);
+   }
+   */
+   return(ncpu);
+}
+
+/* FIXME */
+int ProbePointerBits(int *sure)
+{
+   int iret = 32;
+   char *uname;
+   char cmnd[1024], res[1024];
+
+   *sure = 0;
+/*
+ * Note this is a weak probe, archinfo_x86 much better . . .
+ */
+   uname = FindUname(NULL);
+   sprintf(cmnd, "%s -a", uname);
+/*
+ * This probe should be running on backend; if its ptr length is 8, we've
+ * definitely got a 64 bit machine
+ * NOTE: getting 4 could be a result of compiler flags on a 64-bit arch,
+ * so reverse is not dispositive
+ */
+   if (sizeof(void*) == 8)
+   {
+      iret = 64;
+      *sure = 1;
+   }
+
+   else if (!CmndOneLine(NULL, cmnd, res))
+   {
+/*
+ *    If uname is a known 64-bit platform, we're sure we've got OS support
+ *    for 64bits (may not have compiler support, but that's not our fault)
+ */
+      if (strstr(res, "x86_64") || strstr(res, "ppc64") || strstr(res, "ia64"))
+      {
+         iret = 64;
+         *sure = 1;
+      }
+   }
+   return(iret);
+}
+
+int GetLastFloatScaled(char *ln)
+{
+   int i;
+   float x;
+   i = strlen(ln);
+   for (i=strlen(ln); i>0 ; i--) 
+     {
+       /* Search for the decimal dot */
+       if (strncmp(ln+i, ".",1) == 0)
+	 {
+	   i--;
+	   break;
+	 }
+     }
+   x = strtof(ln+i, NULL);
+   /* Scale from GHz to MHz */
+   x = x*1000;
+   if (x == 0) assert( x == 0);
+   return(x);
+}
+
+int ProbeMhz()
+{
+   int mhz = 0;
+   double x = 0;
+   char res[1024];
+   if (!CmndOneLine(NULL, "x86info | grep GHz", res))
+   {
+       x = GetLastFloatScaled(res);
+       mhz = (int)x;
+   }
+   return(mhz);
+}
+
+/* FIXME */
+int ProbeThrottle()
+/*
+ * RETURNS: 1 if cpu throttling is detected, 0 otherwise
+ */
+{
+   int iret=0;
+   int imax=0, imin=0, icur=0;
+   char res[1024];
+
+/*
+ * If cpufreq directory doesn't exist, guess no throttling.  If
+ * cpufreq exists, and cur Mhz < max, throttling is enabled,
+ * throttling also enabled if governer is not "performance", and min freq
+ * is less than max
+ */
+   if (!CmndOneLine(NULL,
+       "cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", res) )
+   {
+      imax = GetFirstInt(res);
+      assert(!CmndOneLine(NULL,
+             "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", res));
+      imin = GetFirstInt(res);
+      assert(!CmndOneLine(NULL,
+             "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq", res));
+      icur = GetFirstInt(res);
+      assert(!CmndOneLine(NULL,
+             "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", res));
+      if (icur < imax)
+         iret = 1;
+      else if (!strstr(res, "performance") && imin < imax)
+         iret = 1;
+   }
+   return(iret);
+}
+
+main(int nargs, char **args)
+{
+   int flags, CacheLevel, ncpu, mhz, bits, sure;
+   enum MACHTYPE arch=MACHOther;
+
+   flags = GetFlags(nargs, args, &CacheLevel);
+   if (flags & Parch)
+   {
+      arch = ProbeArch();
+      if (flags & Pverb)
+         printf("Architecture detected as %s.\n", machnam[arch]);
+      printf("MACHTYPE=%d\n", arch);
+   }
+   if (flags & Pncpu)
+      printf("NCPU=%d\n", ProbeNCPU());
+   if (flags & PMhz)
+      printf("CPU MHZ=%d\n", ProbeMhz());
+   if (flags & Pthrottle)
+      printf("CPU THROTTLE=%d\n", ProbeThrottle());
+   if (flags & P64)
+   {
+      bits = ProbePointerBits(&sure);
+      printf("PTR BITS=%d, SURE=%d\n", bits, sure);
+   }
+
+/*
+ * Here for future, presently unsupported
+ */
+   if (flags & Pncache)
+      printf("NCACHES=0\n");
+   if (flags & PCacheSize)
+      printf("%d Cache size (kb) = 0\n", CacheLevel);
+   exit(0);
+}
diff -urN atlas-3.8.4/CONFIG/src/Makefile atlas-3.8.4.patched/CONFIG/src/Makefile
--- atlas-3.8.4/CONFIG/src/Makefile	2012-09-06 23:26:20.000000000 +0200
+++ atlas-3.8.4.patched/CONFIG/src/Makefile	2012-09-09 10:37:34.000000000 +0200
@@ -258,6 +258,11 @@
 	$(MAKE) $(atlrun) atldir=$(mydir) exe=xarchinfo_linux args="$(args)" \
                 redir=config0.out
 	- cat config0.out
+IRunArchInfo_gnu: xarchinfo_gnu
+	- rm -f config0.out
+	$(MAKE) $(atlrun) atldir=$(mydir) exe=xarchinfo_gnu args="$(args)" \
+                redir=config0.out
+	- cat config0.out
 IRunArchInfo_x86: xarchinfo_x86
 	- rm -f config0.out
 	$(MAKE) $(atlrun) atldir=$(mydir) exe=xarchinfo_x86 args="$(args)" \
@@ -266,6 +271,9 @@
 xarchinfo_x86: $(SRCdir)/backend/archinfo_x86.c $(SRCdir)/backend/cpuid.S
 	$(CC) $(CCFLAGS) -o xarchinfo_x86 $(SRCdir)/backend/archinfo_x86.c \
               $(SRCdir)/backend/cpuid.S
+xarchinfo_gnu: $(SRCdir)/backend/archinfo_gnu.c atlconf_misc_BE.o
+	$(CC) $(CCFLAGS) -o xarchinfo_gnu $(SRCdir)/backend/archinfo_gnu.c \
+              atlconf_misc_BE.o -lm
 xarchinfo_aix : $(SRCdir)/backend/archinfo_aix.c atlconf_misc_BE.o
 	$(CC) $(CCFLAGS) -o xarchinfo_aix $(SRCdir)/backend/archinfo_aix.c \
               atlconf_misc_BE.o
diff -urN atlas-3.8.4/CONFIG/src/probe_OS.c atlas-3.8.4.patched/CONFIG/src/probe_OS.c
--- atlas-3.8.4/CONFIG/src/probe_OS.c	2011-05-14 19:33:24.000000000 +0200
+++ atlas-3.8.4.patched/CONFIG/src/probe_OS.c	2012-09-09 10:55:49.000000000 +0200
@@ -16,10 +16,11 @@
    {
 /*
  *
- *    Accept GNU (HURD) as Linux, since they seem to use same stuff;
- *    This is patch from Sylvestre Ledru; I have no direct experience wt HURD
+ *    Create a GNU/Hurd specific configuration
+ *    This patch is from Svante Signell
  */
-      if(strstr(ln, "Linux") || strstr(ln, "GNU")) OS = OSLinux;
+      if(strstr(ln, "Linux")) OS = OSLinux;
+      else if (strstr(ln, "GNU")) OS = OSGNU;
       else if(strstr(ln, "FreeBSD")) OS = OSFreeBSD;
       else if (strstr(ln, "Darwin")) OS = OSOSX;
       else if(strstr(ln, "SunOS"))
diff -urN atlas-3.8.4/debian/control atlas-3.8.4.patched/debian/control
--- atlas-3.8.4/debian/control	2012-06-29 21:14:22.000000000 +0200
+++ atlas-3.8.4.patched/debian/control	2012-09-05 22:14:57.000000000 +0200
@@ -9,7 +9,7 @@
 Build-Depends: debhelper (>= 7), patch, gfortran, cdbs,
  libblas-dev  (>= 1.2.20110419-3),
  liblapack-dev (>= 3.4.1-1), liblapack-pic (>= 3.4.1-1), libblas-test,
- texlive-latex-base, ghostscript, cpufrequtils
+ texlive-latex-base, ghostscript, cpufrequtils [!hurd-any], x86info [hurd-any]
 Homepage: http://math-atlas.sourceforge.net/
 Vcs-Svn: svn://svn.debian.org/svn/debian-science/packages/atlas/
 Vcs-Browser: http://svn.debian.org/viewsvn/debian-science/packages/atlas/

Reply to: