Index: fit.py
===================================================================
--- fit.py	(revision 87985ca5989a70a24a7e9ac09a971d544fe16dfe)
+++ fit.py	(revision abb22f4ee986dc647ba9d8269ba50e48f4b4a0f4)
@@ -20,4 +20,5 @@
 data = radial_data if section is not "tangent" else tan_data
 kernel = sas.load_model(name, dtype="single")
+cutoff = 1e-3
 
 if name == "ellipsoid":
@@ -40,5 +41,5 @@
     #model.theta_pd.range(0, 360)
     #model.background.range(0,1000)
-    model.scale.range(0, 1)
+    model.scale.range(0, 10)
 
 
@@ -71,25 +72,24 @@
         """
     pars = dict(
-        scale=.01, radius=64.1, length=66.96, sld=.291, solvent_sld=5.77, background=.1,
+        scale=.01, background=35,
+        sld=.291, solvent_sld=5.77, 
+        radius=250, length=178, 
         theta=90, phi=0,
-        radius_pd=0.1, radius_pd_n=10, radius_pd_nsigma=3,
+        radius_pd=0.1, radius_pd_n=5, radius_pd_nsigma=3,
         length_pd=0.1,length_pd_n=5, length_pd_nsigma=3,
-        theta_pd=0.1, theta_pd_n=5, theta_pd_nsigma=3,
-        phi_pd=0.1, phi_pd_n=10, phi_pd_nsigma=3)
+        theta_pd=10, theta_pd_n=50, theta_pd_nsigma=3,
+        phi_pd=0, phi_pd_n=10, phi_pd_nsigma=3)
     model = sas.BumpsModel(data, kernel, **pars)
-
-
 
     # SET THE FITTING PARAMETERS
     model.radius.range(1, 500)
     model.length.range(1, 5000)
-    #model.theta.range(-90,100)
-    #model.theta_pd.range(0, 90)
-    #model.theta_pd_n = model.theta_pd + 5
-    #model.radius_pd.range(0, 90)
-    #model.length_pd.range(0, 90)
-    model.scale.range(0, 1)
-    #model.background.range(0, 100)
-    #model.sld.range(0, 1)
+    model.theta.range(-90,100)
+    model.theta_pd.range(0, 30)
+    model.theta_pd_n = model.theta_pd + 5
+    model.radius_pd.range(0, 1)
+    model.length_pd.range(0, 2)
+    model.scale.range(0, 10)
+    model.background.range(0, 100)
 
 
@@ -161,4 +161,5 @@
     sys.exit(1)
 
+model.cutoff = cutoff
 if section is "both":
    tan_model = sas.BumpsModel(tan_data, model.model, model.parameters())
@@ -167,3 +168,2 @@
 else:
    problem = FitProblem(model)
-
Index: sasmodels/bumps_model.py
===================================================================
--- sasmodels/bumps_model.py	(revision 87985ca5989a70a24a7e9ac09a971d544fe16dfe)
+++ sasmodels/bumps_model.py	(revision abb22f4ee986dc647ba9d8269ba50e48f4b4a0f4)
@@ -249,9 +249,11 @@
     def __init__(self, data, model, cutoff=1e-5, **kw):
         from bumps.names import Parameter
-        partype = model.info['partype']
 
         # remember inputs so we can inspect from outside
         self.data = data
         self.model = model
+        self.cutoff = cutoff
+
+        partype = model.info['partype']
 
         # interpret data
@@ -271,14 +273,12 @@
             self._theory = np.zeros_like(data.y)
             q_vectors = [data.x]
-        #input = model.make_input(q_vectors)
-        input = model.make_input([v[self.index] for v in q_vectors])
-
-        # create model
-        self.fn = model(input)
-        self.cutoff = cutoff
+
+        # Remember function inputs so we can delay loading the function and
+        # so we can save/restore state
+        self._fn_inputs = [v[self.index] for v in q_vectors]
+        self._fn = None
 
         # define bumps parameters
         pars = []
-        extras = []
         for p in model.info['parameters']:
             name, default, limits, ptype = p[0], p[2], p[3], p[4]
@@ -315,9 +315,13 @@
     def theory(self):
         if 'theory' not in self._cache:
-            pars = [getattr(self,p).value for p in self.fn.fixed_pars]
-            pd_pars = [self._get_weights(p) for p in self.fn.pd_pars]
+            if self._fn is None:
+                input = self.model.make_input(self._fn_inputs)
+                self._fn = self.model(input)
+
+            pars = [getattr(self,p).value for p in self._fn.fixed_pars]
+            pd_pars = [self._get_weights(p) for p in self._fn.pd_pars]
             #print pars
-            self._theory[self.index] = self.fn(pars, pd_pars, self.cutoff)
-            #self._theory[:] = self.fn.eval(pars, pd_pars)
+            self._theory[self.index] = self._fn(pars, pd_pars, self.cutoff)
+            #self._theory[:] = self._fn.eval(pars, pd_pars)
             self._cache['theory'] = self._theory
         return self._cache['theory']
@@ -344,6 +348,6 @@
         from . import weights
 
-        relative = self.fn.info['partype']['pd-rel']
-        limits = self.fn.info['limits']
+        relative = self.model.info['partype']['pd-rel']
+        limits = self.model.info['limits']
         disperser,value,npts,width,nsigma = [getattr(self, par+ext)
                 for ext in ('_pd_type','','_pd_n','_pd','_pd_nsigma')]
@@ -353,4 +357,13 @@
         return v,w/w.max()
 
+    def __getstate__(self):
+        # Can't pickle gpu functions, so instead make them lazy
+        state = self.__dict__.copy()
+        state['_fn'] = None
+        return state
+
+    def __setstate__(self, state):
+        self.__dict__ = state
+
 
 def demo():
