diff --git a/loopy/library/reduction.py b/loopy/library/reduction.py
index 5daa1528a7d67c0dc35644dc40c6d179dc01527e..0e5a093b76b8d09d331edead7c69fcc2e3134601 100644
--- a/loopy/library/reduction.py
+++ b/loopy/library/reduction.py
@@ -422,13 +422,6 @@ def parse_reduction_op(name):
 # }}}
 
 
-def reduction_function_identifiers():
-    """ Return a :class:`set` of the type of the reduction identifiers that can be
-    encountered in a kernel.
-    """
-    return set(op for op in _REDUCTION_OPS)
-
-
 def reduction_function_mangler(kernel, func_id, arg_dtypes):
     if isinstance(func_id, ArgExtOp):
         from loopy.target.opencl import CTarget
diff --git a/loopy/preprocess.py b/loopy/preprocess.py
index e7472ddd6d059ca19b6d48c1ad84a00a2976f376..34fe6e830c3f3a3cf42d6b77a12fda54c727276f 100644
--- a/loopy/preprocess.py
+++ b/loopy/preprocess.py
@@ -893,6 +893,7 @@ def _insert_subdomain_into_domain_tree(kernel, domains, subdomain):
 # }}}
 
 
+
 def realize_reduction(kernel, insn_id_filter=None, unknown_types_ok=True,
                       automagic_scans_ok=False, force_scan=False,
                       force_outer_iname_for_scan=None):
@@ -1093,6 +1094,8 @@ def realize_reduction(kernel, insn_id_filter=None, unknown_types_ok=True,
                 within_inames_is_final=insn.within_inames_is_final,
                 predicates=insn.predicates,)
 
+        reduction_insn = scope_function_in_insn(reduction_insn, kenrel)
+
         generated_insns.append(reduction_insn)
 
         new_insn_add_depends_on.add(reduction_insn.id)
@@ -2145,7 +2148,7 @@ def check_functions_are_scoped(kernel):
         unscoped_calls = UnScopedCallCollector()(insn.expression)
         if unscoped_calls:
             raise LoopyError("Unknown function '%s' obtained -- register a function"
-                    " or a kernel corresponding to it." % unscoped_calls.pop())
+                    " or a kernel corresponding to it." % set(unscoped_calls).pop())
 
 # }}}
 
@@ -2362,10 +2365,6 @@ def preprocess_kernel(kernel, device=None):
     from loopy.transform.subst import expand_subst
     kernel = expand_subst(kernel)
 
-    # Checking if all the functions being used in the kernel and scoped to a
-    # finite namespace
-    check_functions_are_scoped(kernel)
-
     # Ordering restriction:
     # Type inference and reduction iname uniqueness don't handle substitutions.
     # Get them out of the way.
@@ -2382,6 +2381,10 @@ def preprocess_kernel(kernel, device=None):
     from loopy.kernel.creation import apply_single_writer_depencency_heuristic
     kernel = apply_single_writer_depencency_heuristic(kernel)
 
+    # inferring the shape and dim_tags of the arguments involved in a function
+    # call.
+    kernel = infer_arg_descr(kernel)
+
     # Ordering restrictions:
     #
     # - realize_reduction must happen after type inference because it needs
@@ -2410,10 +2413,6 @@ def preprocess_kernel(kernel, device=None):
     # have been established
     kernel = check_atomic_loads(kernel)
 
-    # inferring the shape and dim_tags of the arguments involved in a function
-    # call.
-    kernel = infer_arg_descr(kernel)
-
     kernel = kernel.target.preprocess(kernel)
 
     logger.info("%s: preprocess done" % kernel.name)
diff --git a/loopy/type_inference.py b/loopy/type_inference.py
index f974e3fab846befee53d3ad4dcfa47cf4b0da427..11113538eeadb4fc103bdc15cacc54899bcb864d 100644
--- a/loopy/type_inference.py
+++ b/loopy/type_inference.py
@@ -269,27 +269,24 @@ class TypeInferenceMapper(CombineMapper):
             else:
                 return None
 
-        arg_dtypes = tuple(none_if_empty(self.rec(par)) for par in expr.parameters)
-        if None in arg_dtypes:
-            return []
-
-        arg_id_to_dtype = dict((i, dtype) for (i, dtype) in
-                enumerate(arg_dtypes))
+        arg_id_to_dtype = dict((i, none_if_empty(self.rec(par))) for (i, par) in
+                enumerate(expr.parameters))
 
         # specializing the known function wrt type
-        in_knl_callable = (
-                self.scoped_functions[expr.function.name].with_types(
-                    arg_id_to_dtype, self.kernel.target))
+        if isinstance(expr.function, ScopedFunction):
+            in_knl_callable = (
+                    self.scoped_functions[expr.function.name].with_types(
+                        arg_id_to_dtype, self.kernel.target))
 
-        # storing the type specialized function so that it can be used for
-        # later use
-        self.specialized_functions[expr] = in_knl_callable
+            # storing the type specialized function so that it can be used for
+            # later use
+            self.specialized_functions[expr] = in_knl_callable
 
-        new_arg_id_to_dtype = in_knl_callable.arg_id_to_dtype
+            new_arg_id_to_dtype = in_knl_callable.arg_id_to_dtype
 
-        # collecting result dtypes in order of the assignees
-        if -1 in new_arg_id_to_dtype and new_arg_id_to_dtype[-1] is not None:
-            return [new_arg_id_to_dtype[-1]]
+            # collecting result dtypes in order of the assignees
+            if -1 in new_arg_id_to_dtype and new_arg_id_to_dtype[-1] is not None:
+                return [new_arg_id_to_dtype[-1]]
 
         return []
 
@@ -501,6 +498,12 @@ def infer_unknown_types(kernel, expect_completion=False):
 
     logger.debug("%s: infer types" % kernel.name)
 
+    if expect_completion:
+        # if completion is expected, then it is important that all the
+        # callables are scoped.
+        from loopy.preprocess import check_functions_are_scoped
+        check_functions_are_scoped(kernel)
+
     from functools import partial
     debug = partial(_debug, kernel)