{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# default_exp utils"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Utils\n",
    "\n",
    "> Basic utilities with few dependencies."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "from nbdev.showdoc import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%load_ext autoreload\n",
    "%autoreload 2\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# export\n",
    "import inspect\n",
    "import torch"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "At training time, we will typically want to put the model and the current mini batch on the GPU. When developing on a CPU, a GPU isn't available, so we define a variable that will automatically find the right device. This goes in utils rather than core to avoid circular imports with the callbacks module."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# export\n",
    "DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "device(type='cpu')"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "DEVICE"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# export\n",
    "def hasarg(func, arg):\n",
    "    \"\"\"Checks if a function has a given argument. \n",
    "    Works with args and kwargs as well if you exclude the\n",
    "    stars. See example below.\n",
    "    \n",
    "    Parameters\n",
    "    ----------\n",
    "    func: function\n",
    "    arg: str\n",
    "        Name of argument to look for.\n",
    "    \n",
    "    Returns\n",
    "    -------\n",
    "    bool\n",
    "    \n",
    "    Example\n",
    "    -------\n",
    "    def foo(a, b=6, *args):\n",
    "        return\n",
    "        \n",
    "    >>> hasarg(foo, 'b')\n",
    "    True\n",
    "    \n",
    "    >>> hasarg(foo, 'args')\n",
    "    True\n",
    "    \n",
    "    >>> hasarg(foo, 'c')\n",
    "    False\n",
    "    \"\"\"\n",
    "    return arg in inspect.signature(func).parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# export\n",
    "def quick_stats(x, digits=3):\n",
    "    \"\"\"Quick wrapper to get mean and standard deviation of a tensor.\n",
    "    \n",
    "    Parameters\n",
    "    ----------\n",
    "    x: torch.Tensor\n",
    "    digits: int\n",
    "        Number of digits to round mean and standard deviation to.\n",
    "        \n",
    "    Returns\n",
    "    -------\n",
    "    tuple[float]\n",
    "    \"\"\"\n",
    "    return round(x.mean().item(), digits), round(x.std().item(), digits)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
