code: def run_tutorial(
      tutorial: Path, smoke_test: bool = False
  ) -> Tuple[Optional[str], Dict[str, Any]]:
      """
      Runs the tutorial in a subprocess, catches any raised errors and returns
      them as a string, and returns runtime and memory information as a dict.
      """
      timeout_minutes = 5 if smoke_test else 30
      tic = time.monotonic()
      print(f"Running tutorial {tutorial.name}.")
      env = {"SMOKE_TEST": "True"} if smoke_test else None
      try:
          mem_usage, run_out = memory_usage(
              (run_script, (tutorial, timeout_minutes), {"env": env}),
              retval=True,
              include_children=True,
          )
      except subprocess.TimeoutExpired:
          error = (
              f"Tutorial {tutorial.name} exceeded the maximum runtime of "
              f"{timeout_minutes} minutes."
          )
          return error, {}
  
      try:
          run_out.check_returncode()
      except CalledProcessError:
          error = "\n".join(
              [
                  f"Encountered error running tutorial {tutorial.name}:",
                  "stdout:",
                  run_out.stdout,
                  "stderr:",
                  run_out.stderr,
              ]
          )
          return error, {}
      runtime = time.monotonic() - tic
      performance_info = {
          "runtime": runtime,
          "start_mem": mem_usage[0],
          "max_mem": max(mem_usage),
      }
  
      return None, performance_info
  
file_path: botorch/scripts/run_tutorials.py
imports: from __future__ import annotations
  import argparse
  import datetime
  import os
  import subprocess
  import time
  from pathlib import Path
  from subprocess import CalledProcessError
  from typing import Any, Dict, Optional, Tuple
  import pandas
  from memory_profiler import memory_usage
label_desc: Use image node_id 5 for calling a global function with example usage: run_tutorial(tutorial, smoke_test) and returns: None,  performance_info, error,  dict, error,  dict