Index: gen_so.py
===================================================================
--- gen_so.py	(revision e1454ab1a3d472a0b06129545398ff11c63f49e4)
+++ gen_so.py	(revision bfdfb23e61184d11705d084fd32d0b97cd87cfbe)
@@ -9,12 +9,9 @@
 
     # Convert ../sasmodels/models/name.py to name
-    model_loc = os.path.join(sasmodels, "sasmodels", "models") 
-    for i in os.listdir(model_loc):
+    for model_name in core.list_models():
         # Choose only relevant python files
-        if i.endswith(".py") and not i.startswith("_"):
-            model_name = os.path.basename(i)[:-3]
-            model_info = core.load_model_info(model_name)
+            # model_info = core.load_model_info(model_name)
             # Run the conversion but don't delete the .so
-            model = core.build_model(model_info)
+            model = core.precompile_dll(model_name)
 
 if __name__ == "__main__":
Index: sasmodels/kernel_template.c
===================================================================
--- sasmodels/kernel_template.c	(revision 0278e3fec71d4a97458c09903fd5e3bd354166c1)
+++ sasmodels/kernel_template.c	(revision 98cb4d76ef2c543de605ea2fe00e4c03b7600144)
@@ -24,28 +24,6 @@
          inline double isnan(double x) { return _isnan(x); }
          #define NAN (std::numeric_limits<double>::quiet_NaN()) // non-signalling NaN
-         static double cephes_expm1(double x) {
-            // Adapted from the cephes math library.
-            // Copyright 1984 - 1992 by Stephen L. Moshier
-            if (x != x || x == 0.0) {
-               return x; // NaN and +/- 0
-            } else if (x < -0.5 || x > 0.5) {
-               return exp(x) - 1.0;
-            } else {
-               const double xsq = x*x;
-               const double p = (((
-                  +1.2617719307481059087798E-4)*xsq
-                  +3.0299440770744196129956E-2)*xsq
-                  +9.9999999999999999991025E-1);
-               const double q = ((((
-                  +3.0019850513866445504159E-6)*xsq
-                  +2.5244834034968410419224E-3)*xsq
-                  +2.2726554820815502876593E-1)*xsq
-                  +2.0000000000000000000897E0);
-               double r = x * p;
-               r =  r / (q - r);
-               return r+r;
-             }
-         }
-         #define expm1 cephes_expm1
+         #define NEED_EXPM1
+         #define NEED_TGAMMA
      #else
          #define kernel extern "C"
@@ -74,4 +52,30 @@
 #endif
 
+#if defined(NEED_EXPM1)
+   static double expm1(double x) {
+      // Adapted from the cephes math library.
+      // Copyright 1984 - 1992 by Stephen L. Moshier
+      if (x != x || x == 0.0) {
+         return x; // NaN and +/- 0
+      } else if (x < -0.5 || x > 0.5) {
+         return exp(x) - 1.0;
+      } else {
+         const double xsq = x*x;
+         const double p = (((
+            +1.2617719307481059087798E-4)*xsq
+            +3.0299440770744196129956E-2)*xsq
+            +9.9999999999999999991025E-1);
+         const double q = ((((
+            +3.0019850513866445504159E-6)*xsq
+            +2.5244834034968410419224E-3)*xsq
+            +2.2726554820815502876593E-1)*xsq
+            +2.0000000000000000000897E0);
+         double r = x * p;
+         r =  r / (q - r);
+         return r+r;
+       }
+   }
+#endif
+
 // Standard mathematical constants:
 //   M_E, M_LOG2E, M_LOG10E, M_LN2, M_LN10, M_PI, M_PI_2=pi/2, M_PI_4=pi/4,
Index: sasmodels/models/lib/sas_gamma.c
===================================================================
--- sasmodels/models/lib/sas_gamma.c	(revision ad9af31d75a4f3938e9694c12b5015b4c6efec6b)
+++ sasmodels/models/lib/sas_gamma.c	(revision 98cb4d76ef2c543de605ea2fe00e4c03b7600144)
@@ -1,5 +1,5 @@
 /*
 The wrapper for gamma function from OpenCL and standard libraries
-The OpenCL gamma function fails misserably on values lower than 1.0
+The OpenCL gamma function fails miserably on values lower than 1.0
 while works fine on larger values.
 We use gamma definition Gamma(t + 1) = t * Gamma(t) to compute
@@ -7,4 +7,133 @@
 */
 
+#if defined(NEED_TGAMMA)
+static double cephes_stirf(double x)
+{
+	const double MAXSTIR=143.01608;
+	const double SQTPI=2.50662827463100050242E0;
+	double y, w, v;
+
+	w = 1.0 / x;
+
+	w = ((((
+		7.87311395793093628397E-4*w
+		- 2.29549961613378126380E-4)*w
+		- 2.68132617805781232825E-3)*w
+		+ 3.47222221605458667310E-3)*w
+		+ 8.33333333333482257126E-2)*w
+		+ 1.0;
+	y = exp(x);
+	if (x > MAXSTIR)
+	{ /* Avoid overflow in pow() */
+		v = pow(x, 0.5 * x - 0.25);
+		y = v * (v / y);
+	}
+	else
+	{
+		y = pow(x, x - 0.5) / y;
+	}
+	y = SQTPI * y * w;
+	return(y);
+}
+
+static double tgamma(double x) {
+	double p, q, z;
+	int sgngam;
+	int i;
+
+	sgngam = 1;
+	if (isnan(x))
+		return(x);
+	q = fabs(x);
+
+	if (q > 33.0)
+	{
+		if (x < 0.0)
+		{
+			p = floor(q);
+			if (p == q)
+			{
+				return (NAN);
+			}
+			i = p;
+			if ((i & 1) == 0)
+				sgngam = -1;
+			z = q - p;
+			if (z > 0.5)
+			{
+				p += 1.0;
+				z = q - p;
+			}
+			z = q * sin(M_PI * z);
+			if (z == 0.0)
+			{
+				return(NAN);
+			}
+			z = fabs(z);
+			z = M_PI / (z * cephes_stirf(q));
+		}
+		else
+		{
+			z = cephes_stirf(x);
+		}
+		return(sgngam * z);
+	}
+
+	z = 1.0;
+	while (x >= 3.0)
+	{
+		x -= 1.0;
+		z *= x;
+	}
+
+	while (x < 0.0)
+	{
+		if (x > -1.E-9)
+			goto small;
+		z /= x;
+		x += 1.0;
+	}
+
+	while (x < 2.0)
+	{
+		if (x < 1.e-9)
+			goto small;
+		z /= x;
+		x += 1.0;
+	}
+
+	if (x == 2.0)
+		return(z);
+
+	x -= 2.0;
+	p = (((((
+		+1.60119522476751861407E-4*x
+		+ 1.19135147006586384913E-3)*x
+		+ 1.04213797561761569935E-2)*x
+		+ 4.76367800457137231464E-2)*x
+		+ 2.07448227648435975150E-1)*x
+		+ 4.94214826801497100753E-1)*x
+		+ 9.99999999999999996796E-1;
+	q = ((((((
+		-2.31581873324120129819E-5*x
+		+ 5.39605580493303397842E-4)*x
+		- 4.45641913851797240494E-3)*x
+		+ 1.18139785222060435552E-2)*x
+		+ 3.58236398605498653373E-2)*x
+		- 2.34591795718243348568E-1)*x
+		+ 7.14304917030273074085E-2)*x
+		+ 1.00000000000000000320E0;
+	return(z * p / q);
+
+small:
+	if (x == 0.0)
+	{
+		return (NAN);
+	}
+	else
+		return(z / ((1.0 + 0.5772156649015329 * x) * x));
+}
+#endif
+
 
 inline double sas_gamma( double x) { return tgamma(x+1)/x; }
