code: def make_sample_fn(model, **sample_kwargs):
      """Create a sample function from a model with better error reporting.
  
      The returned generator generates samples from the model, printing an error if
      something went wrong.
  
      Args:
        model: A `CmdStanModel`.
        **sample_kwargs: Arguments to pass to `CmdStanModel.sample`.
  
      Returns:
        sample_fn: A generator with signature
          `(output_dir, **kwargs) -> cmdstanpy.CmdStanMCMC`.
          `output_base_dir` specifies the base directory to use for the temporary
          directory created to hold Stan's outputs.
      """
  
      @contextlib.contextmanager
      def _sample_fn(output_dir=None, **kwargs):
          """The sample function."""
          # Error reporting isn't great in CmdStanPy yet
          # (https://github.com/stan-dev/cmdstanpy/issues/22), so we do a little work
          # to intercept the console output and print it if there's an issue.
          #
          # We use a context manager because CmdStanPy lazily loads quantities from
          # the output directory, and since we're in control of deleting it, we need
          # to have a mechanism to keep it around until the user is done with it.
          if output_dir is None:
              output_dir = tempfile.mkdtemp()
              keep_outputs = False
          else:
              keep_outputs = True
          final_kwargs = sample_kwargs.copy()
          final_kwargs.update(kwargs)
          if "data" in final_kwargs:
              # Canonicalize the data to be all NumPy arrays,
              final_kwargs["data"] = {
                  k: np.array(v)
                  for k, v in final_kwargs["data"].items()
              }
          try:
              yield model.sample(output_dir=output_dir, **final_kwargs)
          except RuntimeError as e:
              for console_filename in glob.glob(
                  os.path.join(output_dir, "*.txt")
              ):
                  with open(console_filename, "r") as f:
                      print(console_filename)
                      print(f.read())
              raise e
          finally:
              if not keep_outputs:
                  shutil.rmtree(output_dir)
  
      return _sample_fn
  
file_path: probability/spinoffs/inference_gym/inference_gym/tools/stan/util.py
imports: import contextlib
  import glob
  import hashlib
  import os
  import re
  import shutil
  import tempfile
  from absl import flags
  import cmdstanpy
  import numpy
label_desc: Use image node_id 3 for calling a global function with example usage: make_sample_fn(model) and returns: _sample_fn