diff --git a/.venv/lib/python3.11/site-packages/colorful/colors.py b/.venv/lib/python3.11/site-packages/colorful/colors.py new file mode 100644 index 0000000000000000000000000000000000000000..d075d72f5fc0b4a5474a4ce1da73e44671dc9e90 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/colorful/colors.py @@ -0,0 +1,101 @@ +# -*- coding: utf-8 -*- + +""" + colorful + ~~~~~~~~ + + Terminal string styling done right, in Python. + + :copyright: (c) 2017 by Timo Furrer + :license: MIT, see LICENSE for more details. +""" + +import json + +from . import utils + + +def parse_colors(path): + """Parse the given color files. + + Supported are: + * .txt for X11 colors + * .json for colornames + """ + if path.endswith(".txt"): + return parse_rgb_txt_file(path) + elif path.endswith(".json"): + return parse_json_color_file(path) + + raise TypeError("colorful only supports .txt and .json files for colors") + + +def parse_rgb_txt_file(path): + """ + Parse the given rgb.txt file into a Python dict. + + See https://en.wikipedia.org/wiki/X11_color_names for more information + + :param str path: the path to the X11 rgb.txt file + """ + #: Holds the generated color dict + color_dict = {} + + with open(path, 'r') as rgb_txt: + for line in rgb_txt: + line = line.strip() + if not line or line.startswith('!'): + continue # skip comments + + parts = line.split() + color_dict[" ".join(parts[3:])] = (int(parts[0]), int(parts[1]), int(parts[2])) + + return color_dict + + +def parse_json_color_file(path): + """Parse a JSON color file. + + The JSON has to be in the following format: + + .. code:: json + + [{"name": "COLOR_NAME", "hex": "#HEX"}, ...] + + :param str path: the path to the JSON color file + """ + with open(path, "r") as color_file: + color_list = json.load(color_file) + + # transform raw color list into color dict + color_dict = {c["name"]: c["hex"] for c in color_list} + return color_dict + + +def sanitize_color_palette(colorpalette): + """ + Sanitze the given color palette so it can + be safely used by Colorful. + + It will convert colors specified in hex RGB to + a RGB channel triplet. + """ + new_palette = {} + + def __make_valid_color_name(name): + """ + Convert the given name into a valid colorname + """ + if len(name) == 1: + name = name[0] + return name[:1].lower() + name[1:] + + return name[0].lower() + ''.join(word.capitalize() for word in name[1:]) + + for key, value in colorpalette.items(): + if isinstance(value, str): + # we assume it's a hex RGB value + value = utils.hex_to_rgb(value) + new_palette[__make_valid_color_name(key.split())] = value + + return new_palette diff --git a/.venv/lib/python3.11/site-packages/colorful/core.py b/.venv/lib/python3.11/site-packages/colorful/core.py new file mode 100644 index 0000000000000000000000000000000000000000..b5e0b93fb81dcd98708ed92a59fc4c693fc34bce --- /dev/null +++ b/.venv/lib/python3.11/site-packages/colorful/core.py @@ -0,0 +1,551 @@ +# -*- coding: utf-8 -*- + +""" + colorful + ~~~~~~~~ + + Terminal string styling done right, in Python. + + :copyright: (c) 2017 by Timo Furrer + :license: MIT, see LICENSE for more details. +""" + +import os + +from . import ansi +from . import colors +from . import styles +from . import terminal + +#: Holds the name of the env variable which is +# used as path to the default rgb.txt file +DEFAULT_RGB_TXT_PATH = os.environ.get( + 'COLORFUL_DEFAULT_COLOR_PALETTE', + os.path.join(os.path.dirname(__file__), 'data', 'rgb.txt')) + +#: Holds the color names mapped to RGB channels +COLOR_PALETTE = colors.parse_colors(path=DEFAULT_RGB_TXT_PATH) + +#: Holds the path to the built-in `colornames` color palette file +COLORNAMES_COLORS_PATH = os.path.join(os.path.dirname(__file__), "data", "colornames.json") + + +class ColorfulError(Exception): + """ + Exception which is raised for Colorful specific + usage errors. + """ + + +class ColorfulAttributeError(AttributeError, ColorfulError): + """ + Exception which is raised for Colorful specific + usage errors raised during ``__getattr__`` calls. + + This is to ensure a correct ``__getattr__`` protocol implementation. + """ + + +def translate_rgb_to_ansi_code(red, green, blue, offset, colormode): + """ + Translate the given RGB color into the appropriate ANSI escape code + for the given color mode. + The offset is used for the base color which is used. + + The ``colormode`` has to be one of: + * 0: no colors / disabled + * 8: use ANSI 8 colors + * 16: use ANSI 16 colors (same as 8 but with brightness) + * 256: use ANSI 256 colors + * 0xFFFFFF / 16777215: use 16 Million true colors + + :param int red: the red channel value + :param int green: the green channel value + :param int blue: the blue channel value + :param int offset: the offset to use for the base color + :param int colormode: the color mode to use. See explanation above + """ + if colormode == terminal.NO_COLORS: # colors are disabled, thus return empty string + return '', '' + + if colormode == terminal.ANSI_8_COLORS or colormode == terminal.ANSI_16_COLORS: + color_code = ansi.rgb_to_ansi16(red, green, blue) + start_code = ansi.ANSI_ESCAPE_CODE.format( + code=color_code + offset - ansi.FOREGROUND_COLOR_OFFSET) + end_code = ansi.ANSI_ESCAPE_CODE.format(code=offset + ansi.COLOR_CLOSE_OFFSET) + return start_code, end_code + + if colormode == terminal.ANSI_256_COLORS: + color_code = ansi.rgb_to_ansi256(red, green, blue) + start_code = ansi.ANSI_ESCAPE_CODE.format(code='{base};5;{code}'.format( + base=8 + offset, code=color_code)) + end_code = ansi.ANSI_ESCAPE_CODE.format(code=offset + ansi.COLOR_CLOSE_OFFSET) + return start_code, end_code + + if colormode == terminal.TRUE_COLORS: + start_code = ansi.ANSI_ESCAPE_CODE.format(code='{base};2;{red};{green};{blue}'.format( + base=8 + offset, red=red, green=green, blue=blue)) + end_code = ansi.ANSI_ESCAPE_CODE.format(code=offset + ansi.COLOR_CLOSE_OFFSET) + return start_code, end_code + + raise ColorfulAttributeError('invalid color mode "{0}"'.format(colormode)) + + +def translate_colorname_to_ansi_code(colorname, offset, colormode, colorpalette): + """ + Translate the given color name to a valid + ANSI escape code. + + :parma str colorname: the name of the color to resolve + :parma str offset: the offset for the color code + :param int colormode: the color mode to use. See ``translate_rgb_to_ansi_code`` + :parma dict colorpalette: the color palette to use for the color name mapping + + :returns str: the color as ANSI escape code + + :raises ColorfulError: if the given color name is invalid + """ + try: + red, green, blue = colorpalette[colorname] + except KeyError: + raise ColorfulAttributeError('the color "{0}" is unknown. Use a color in your color palette (by default: X11 rgb.txt)'.format( # noqa + colorname)) + else: + return translate_rgb_to_ansi_code(red, green, blue, offset, colormode) + + +def resolve_modifier_to_ansi_code(modifiername, colormode): + """ + Resolve the given modifier name to a valid + ANSI escape code. + + :param str modifiername: the name of the modifier to resolve + :param int colormode: the color mode to use. See ``translate_rgb_to_ansi_code`` + + :returns str: the ANSI escape code for the modifier + + :raises ColorfulError: if the given modifier name is invalid + """ + if colormode == terminal.NO_COLORS: # return empty string if colors are disabled + return '', '' + + try: + start_code, end_code = ansi.MODIFIERS[modifiername] + except KeyError: + raise ColorfulAttributeError('the modifier "{0}" is unknown. Use one of: {1}'.format( + modifiername, ansi.MODIFIERS.keys())) + else: + return ansi.ANSI_ESCAPE_CODE.format( + code=start_code), ansi.ANSI_ESCAPE_CODE.format( + code=end_code) + + +def translate_style(style, colormode, colorpalette): + """ + Translate the given style to an ANSI escape code + sequence. + + ``style`` examples are: + + * green + * bold + * red_on_black + * bold_green + * italic_yellow_on_cyan + + :param str style: the style to translate + :param int colormode: the color mode to use. See ``translate_rgb_to_ansi_code`` + :parma dict colorpalette: the color palette to use for the color name mapping + """ + style_parts = iter(style.split('_')) + + ansi_start_sequence = [] + ansi_end_sequence = [] + + try: + # consume all modifiers + part = None + for mod_part in style_parts: + part = mod_part + if part not in ansi.MODIFIERS: + break # all modifiers have been consumed + + mod_start_code, mod_end_code = resolve_modifier_to_ansi_code(part, colormode) + ansi_start_sequence.append(mod_start_code) + ansi_end_sequence.append(mod_end_code) + else: # we've consumed all parts, thus we can exit + raise StopIteration() + + # next part has to be a foreground color or the 'on' keyword + # which means we have to consume background colors + if part != 'on': + ansi_start_code, ansi_end_code = translate_colorname_to_ansi_code( + part, ansi.FOREGROUND_COLOR_OFFSET, colormode, colorpalette) + ansi_start_sequence.append(ansi_start_code) + ansi_end_sequence.append(ansi_end_code) + # consume the required 'on' keyword after the foreground color + next(style_parts) + + # next part has to be the background color + part = next(style_parts) + ansi_start_code, ansi_end_code = translate_colorname_to_ansi_code( + part, ansi.BACKGROUND_COLOR_OFFSET, colormode, colorpalette) + ansi_start_sequence.append(ansi_start_code) + ansi_end_sequence.append(ansi_end_code) + except StopIteration: # we've consumed all parts of the styling string + pass + + # construct and return ANSI escape code sequence + return ''.join(ansi_start_sequence), ''.join(ansi_end_sequence) + + +def style_string(string, ansi_style, colormode, nested=False): + """ + Style the given string according to the given + ANSI style string. + + :param str string: the string to style + :param tuple ansi_style: the styling string returned by ``translate_style`` + :param int colormode: the color mode to use. See ``translate_rgb_to_ansi_code`` + + :returns: a string containing proper ANSI sequence + """ + ansi_start_code, ansi_end_code = ansi_style + + # replace nest placeholders with the current begin style + string = str(string).replace(ansi.NEST_PLACEHOLDER, ansi_start_code) + + return '{start_code}{string}{end_code}{nest_ph}'.format( + start_code=ansi_start_code, + string=string, + end_code=ansi_end_code, + nest_ph=ansi.NEST_PLACEHOLDER if nested else '') + + +class ColorfulString(object): + """ + Represents a colored string + """ + def __init__(self, orig_string, styled_string, colorful_ctx): + self.orig_string = str(orig_string) + self.styled_string = str(styled_string) + self.colorful_ctx = colorful_ctx + + def __str__(self): + if self.colorful_ctx.colormode == terminal.NO_COLORS: + return self.orig_string + else: + return self.styled_string + + def __len__(self): + return len(self.orig_string) + + def __iter__(self): + return iter(self.styled_string) + + def __add__(self, other): + if isinstance(other, ColorfulString): + return ColorfulString( + self.orig_string + other.orig_string, + self.styled_string + other.styled_string, + self.colorful_ctx) + + return ColorfulString( + self.orig_string + other, + self.styled_string + other, + self.colorful_ctx) + + def __iadd__(self, other): + if isinstance(other, ColorfulString): + self.orig_string += other.orig_string + self.styled_string += other.styled_string + else: + self.orig_string += other + self.styled_string += other + + return self + + def __radd__(self, other): + if isinstance(other, ColorfulString): + return ColorfulString( + other.orig_string + self.orig_string, + other.styled_string + self.styled_string, + self.colorful_ctx) + + # we return handover the conversion to the + # object on the left side + return other + self.styled_string + + def __mul__(self, other): + return ColorfulString( + self.orig_string * other, + self.styled_string * other, + self.colorful_ctx) + + def __format__(self, format_spec): + if self.colorful_ctx.colormode == terminal.NO_COLORS: + return self.orig_string.__format__(format_spec) + + # append nested placeholder to styled string in order to continue the + # previous styles. If the string already ends with the nest placeholder + # we don't have to append it again. + if self.styled_string.endswith(ansi.NEST_PLACEHOLDER): + styled_string = self.styled_string + else: + styled_string = '{orig_str}{nest_ph}'.format( + orig_str=self.styled_string, nest_ph=ansi.NEST_PLACEHOLDER) + return styled_string.__format__(format_spec) + + def __getattr__(self, name): + str_method = getattr(self.styled_string, name) + return str_method + + +class Colorful(object): + """ + Provides methods to style strings for terminal + output. + + :param int colormode: the color mode to use. See ``translate_rgb_to_ansi_code`` + """ + # re-expose the color modes from ``colorful.terminal`` + # on a package level. + NO_COLORS = terminal.NO_COLORS + ANSI_8_COLORS = terminal.ANSI_8_COLORS + ANSI_16_COLORS = terminal.ANSI_16_COLORS + ANSI_256_COLORS = terminal.ANSI_256_COLORS + TRUE_COLORS = terminal.TRUE_COLORS + + # expose the `colornames` color palette + COLORNAMES_COLORS = COLORNAMES_COLORS_PATH + + # expose ANSI escape codes to close colors + # this is especially useful when using ``str.format()``. + close_fg_color = ansi.ANSI_ESCAPE_CODE.format( + code=ansi.FOREGROUND_COLOR_OFFSET + ansi.COLOR_CLOSE_OFFSET) + close_bg_color = ansi.ANSI_ESCAPE_CODE.format( + code=ansi.BACKGROUND_COLOR_OFFSET + ansi.COLOR_CLOSE_OFFSET) + + # expose ANSI escape codes to close modifiers + no_bold = ansi.ANSI_ESCAPE_CODE.format(code=ansi.MODIFIERS['bold'][1]) + no_dimmed = ansi.ANSI_ESCAPE_CODE.format(code=ansi.MODIFIERS['dimmed'][1]) + no_italic = ansi.ANSI_ESCAPE_CODE.format(code=ansi.MODIFIERS['italic'][1]) + no_underlined = ansi.ANSI_ESCAPE_CODE.format(code=ansi.MODIFIERS['underlined'][1]) + no_blinkslow = ansi.ANSI_ESCAPE_CODE.format(code=ansi.MODIFIERS['blinkslow'][1]) + no_blinkrapid = ansi.ANSI_ESCAPE_CODE.format(code=ansi.MODIFIERS['blinkrapid'][1]) + no_inversed = ansi.ANSI_ESCAPE_CODE.format(code=ansi.MODIFIERS['inversed'][1]) + no_concealed = ansi.ANSI_ESCAPE_CODE.format(code=ansi.MODIFIERS['concealed'][1]) + no_struckthrough = ansi.ANSI_ESCAPE_CODE.format(code=ansi.MODIFIERS['struckthrough'][1]) + + def __init__(self, colormode=None, colorpalette=None): + if colormode is None: # try to auto-detect color mode + colormode = terminal.detect_color_support(env=os.environ) + + if colorpalette is None: # load default color palette + colorpalette = COLOR_PALETTE + elif isinstance(colorpalette, str): # we assume it's a path to a color file + colorpalette = colors.parse_colors(colorpalette) + + #: Holds the color mode to use for this Colorful object. + self.colormode = colormode + + #: Holds the color palette to use for this Colorful object. + self._colorpalette = None + self.colorpalette = colorpalette + + @property + def colorpalette(self): + """ + Get the current used color palette + """ + return self._colorpalette + + @colorpalette.setter + def colorpalette(self, colorpalette): + """ + Set the colorpalette which should be used + """ + if isinstance(colorpalette, str): # we assume it's a path to a color file + colorpalette = colors.parse_colors(colorpalette) + + self._colorpalette = colors.sanitize_color_palette(colorpalette) + + def setup(self, colormode=None, colorpalette=None, extend_colors=False): + """ + Setup this colorful object by setting a ``colormode`` and + the ``colorpalette`. The ``extend_colors`` flag is used + to extend the currently active color palette instead of + replacing it. + + :param int colormode: the color mode to use. See ``translate_rgb_to_ansi_code`` + :parma dict colorpalette: the colorpalette to use. This ``dict`` should map + color names to it's corresponding RGB value + :param bool extend_colors: extend the active color palette instead of replacing it + """ + if colormode is not None: + self.colormode = colormode + + if colorpalette: + if extend_colors: + self.update_palette(colorpalette) + else: + self.colorpalette = colorpalette + + def disable(self): + """ + Disable all colors and styles + """ + self.colormode = terminal.NO_COLORS + + def use_8_ansi_colors(self): + """ + Use 8 ANSI colors for this colorful object + """ + self.colormode = terminal.ANSI_8_COLORS + + def use_16_ansi_colors(self): + """ + Use 16 ANSI colors for this colorful object + """ + self.colormode = terminal.ANSI_16_COLORS + + def use_256_ansi_colors(self): + """ + Use 256 ANSI colors for this colorful object + """ + self.colormode = terminal.ANSI_256_COLORS + + def use_true_colors(self): + """ + Use true colors for this colorful object + """ + self.colormode = terminal.TRUE_COLORS + + def use_palette(self, colorpalette): + """ + Use the given color palette + """ + self.colorpalette = colorpalette + + def update_palette(self, colorpalette): + """ + Update the currently active color palette + with the given color palette + """ + self.colorpalette.update(colors.sanitize_color_palette(colorpalette)) + + def use_style(self, style_name): + """ + Use a predefined style as color palette + + :param str style_name: the name of the style + """ + try: + style = getattr(styles, style_name.upper()) + except AttributeError: + raise ColorfulError('the style "{0}" is undefined'.format( + style_name)) + else: + self.colorpalette = style + + def format(self, string, *args, **kwargs): + """ + Format the given string with the given ``args`` and ``kwargs``. + The string can contain references to ``c`` which is provided by + this colorful object. + + :param str string: the string to format + """ + return string.format(c=self, *args, **kwargs) + + def str(self, string): + """ + Create a new ColorfulString instance of the given + unstyled string. + + This method should be used to create a ColorfulString + which is actually not styled yet but can safely be concatinated + with other ColorfulStrings like: + + >>> s = colorful.str('Hello ') + >>> s =+ colorful.black('World') + >>> str(s) + 'Hello \033[30mWorld\033[39m' + + :param str string: the string to use for the ColorfulString + """ + return ColorfulString(string, string, self) + + def print(self, *objects, sep=' ', end='\n', file=None, flush=False): + """ + Print the given objects to the given file stream. + See https://docs.python.org/3/library/functions.html#print + + The only difference to the ``print()`` built-in is that + ``Colorful.print()`` formats the string with ``c=self``. + With that stylings are possible + + :param str sep: the seperater between the objects + :param str end: the ending delimiter after all objects + :param file: the file stream to write to + :param bool flush: if the stream should be flushed + """ + styled_objects = [self.format(o) for o in objects] + print(*styled_objects, sep=sep, end=end, file=file, flush=flush) + + class ColorfulStyle(object): + """ + Represents a colorful style + """ + def __init__(self, style, colormode, colorful_ctx): + self.style = style + self.colormode = colormode + self.colorful_ctx = colorful_ctx + + def evaluate(self, string, nested=False): + """ + Evaluate the style on the given string. + + :parma str string: the string to style + :param bool nested: if the string is part of another styled string + (=> nested in another style) + """ + return ColorfulString( + string, + style_string(string, self.style, self.colormode, nested), + self.colorful_ctx) + + def __str__(self): + return self.style[0] + + def __and__(self, other): + new_style = ( + self.style[0] + other.style[0], + self.style[1] + other.style[1] + ) + return Colorful.ColorfulStyle(new_style, self.colormode, self.colorful_ctx) + + def __call__(self, string, nested=False): + return self.evaluate(string, nested) + + def __or__(self, other): + return self.evaluate(other) + + def __eq__(self, other): + if not isinstance(other, Colorful.ColorfulStyle): + return False + + return ( + self.style == other.style and + self.colormode == other.colormode and + self.colorful_ctx == other.colorful_ctx + ) + + def __hash__(self): + return hash((self.style, self.colormode, self.colorful_ctx)) + + def __getattr__(self, name): + # translate the given name into an ANSI escape code sequence + style = translate_style(name, self.colormode, self.colorpalette) + style_wrapper = self.ColorfulStyle(style, self.colormode, self) + return style_wrapper diff --git a/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/INSTALLER b/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/METADATA b/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..a3939b1e88db4fc7d48032d351fee2752b1cf6d5 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/METADATA @@ -0,0 +1,563 @@ +Metadata-Version: 2.1 +Name: fastapi +Version: 0.115.8 +Summary: FastAPI framework, high performance, easy to learn, fast to code, ready for production +Author-Email: =?utf-8?q?Sebasti=C3=A1n_Ram=C3=ADrez?= +Classifier: Intended Audience :: Information Technology +Classifier: Intended Audience :: System Administrators +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python +Classifier: Topic :: Internet +Classifier: Topic :: Software Development :: Libraries :: Application Frameworks +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Software Development :: Libraries +Classifier: Topic :: Software Development +Classifier: Typing :: Typed +Classifier: Development Status :: 4 - Beta +Classifier: Environment :: Web Environment +Classifier: Framework :: AsyncIO +Classifier: Framework :: FastAPI +Classifier: Framework :: Pydantic +Classifier: Framework :: Pydantic :: 1 +Classifier: Framework :: Pydantic :: 2 +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers +Classifier: Topic :: Internet :: WWW/HTTP +Project-URL: Homepage, https://github.com/fastapi/fastapi +Project-URL: Documentation, https://fastapi.tiangolo.com/ +Project-URL: Repository, https://github.com/fastapi/fastapi +Project-URL: Issues, https://github.com/fastapi/fastapi/issues +Project-URL: Changelog, https://fastapi.tiangolo.com/release-notes/ +Requires-Python: >=3.8 +Requires-Dist: starlette<0.46.0,>=0.40.0 +Requires-Dist: pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0,>=1.7.4 +Requires-Dist: typing-extensions>=4.8.0 +Provides-Extra: standard +Requires-Dist: fastapi-cli[standard]>=0.0.5; extra == "standard" +Requires-Dist: httpx>=0.23.0; extra == "standard" +Requires-Dist: jinja2>=3.1.5; extra == "standard" +Requires-Dist: python-multipart>=0.0.18; extra == "standard" +Requires-Dist: email-validator>=2.0.0; extra == "standard" +Requires-Dist: uvicorn[standard]>=0.12.0; extra == "standard" +Provides-Extra: all +Requires-Dist: fastapi-cli[standard]>=0.0.5; extra == "all" +Requires-Dist: httpx>=0.23.0; extra == "all" +Requires-Dist: jinja2>=3.1.5; extra == "all" +Requires-Dist: python-multipart>=0.0.18; extra == "all" +Requires-Dist: itsdangerous>=1.1.0; extra == "all" +Requires-Dist: pyyaml>=5.3.1; extra == "all" +Requires-Dist: ujson!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,>=4.0.1; extra == "all" +Requires-Dist: orjson>=3.2.1; extra == "all" +Requires-Dist: email-validator>=2.0.0; extra == "all" +Requires-Dist: uvicorn[standard]>=0.12.0; extra == "all" +Requires-Dist: pydantic-settings>=2.0.0; extra == "all" +Requires-Dist: pydantic-extra-types>=2.0.0; extra == "all" +Description-Content-Type: text/markdown + +

+ FastAPI +

+

+ FastAPI framework, high performance, easy to learn, fast to code, ready for production +

+

+ + Test + + + Coverage + + + Package version + + + Supported Python versions + +

+ +--- + +**Documentation**: https://fastapi.tiangolo.com + +**Source Code**: https://github.com/fastapi/fastapi + +--- + +FastAPI is a modern, fast (high-performance), web framework for building APIs with Python based on standard Python type hints. + +The key features are: + +* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance). +* **Fast to code**: Increase the speed to develop features by about 200% to 300%. * +* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. * +* **Intuitive**: Great editor support. Completion everywhere. Less time debugging. +* **Easy**: Designed to be easy to use and learn. Less time reading docs. +* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs. +* **Robust**: Get production-ready code. With automatic interactive documentation. +* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: OpenAPI (previously known as Swagger) and JSON Schema. + +* estimation based on tests on an internal development team, building production applications. + +## Sponsors + + + + + + + + + + + + + + + + + + + + + + +Other sponsors + +## Opinions + +"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._" + +
Kabir Khan - Microsoft (ref)
+ +--- + +"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_" + +
Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - Uber (ref)
+ +--- + +"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_" + +
Kevin Glisson, Marc Vilanova, Forest Monsen - Netflix (ref)
+ +--- + +"_Iโ€™m over the moon excited about **FastAPI**. Itโ€™s so fun!_" + +
Brian Okken - Python Bytes podcast host (ref)
+ +--- + +"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._" + +
Timothy Crosley - Hug creator (ref)
+ +--- + +"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_" + +"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_" + +
Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators (ref) - (ref)
+ +--- + +"_If anyone is looking to build a production Python API, I would highly recommend **FastAPI**. It is **beautifully designed**, **simple to use** and **highly scalable**, it has become a **key component** in our API first development strategy and is driving many automations and services such as our Virtual TAC Engineer._" + +
Deon Pillsbury - Cisco (ref)
+ +--- + +## **Typer**, the FastAPI of CLIs + + + +If you are building a CLI app to be used in the terminal instead of a web API, check out **Typer**. + +**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. โŒจ๏ธ ๐Ÿš€ + +## Requirements + +FastAPI stands on the shoulders of giants: + +* Starlette for the web parts. +* Pydantic for the data parts. + +## Installation + +Create and activate a virtual environment and then install FastAPI: + +
+ +```console +$ pip install "fastapi[standard]" + +---> 100% +``` + +
+ +**Note**: Make sure you put `"fastapi[standard]"` in quotes to ensure it works in all terminals. + +## Example + +### Create it + +* Create a file `main.py` with: + +```Python +from typing import Union + +from fastapi import FastAPI + +app = FastAPI() + + +@app.get("/") +def read_root(): + return {"Hello": "World"} + + +@app.get("/items/{item_id}") +def read_item(item_id: int, q: Union[str, None] = None): + return {"item_id": item_id, "q": q} +``` + +
+Or use async def... + +If your code uses `async` / `await`, use `async def`: + +```Python hl_lines="9 14" +from typing import Union + +from fastapi import FastAPI + +app = FastAPI() + + +@app.get("/") +async def read_root(): + return {"Hello": "World"} + + +@app.get("/items/{item_id}") +async def read_item(item_id: int, q: Union[str, None] = None): + return {"item_id": item_id, "q": q} +``` + +**Note**: + +If you don't know, check the _"In a hurry?"_ section about `async` and `await` in the docs. + +
+ +### Run it + +Run the server with: + +
+ +```console +$ fastapi dev main.py + + โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ FastAPI CLI - Development mode โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ + โ”‚ โ”‚ + โ”‚ Serving at: http://127.0.0.1:8000 โ”‚ + โ”‚ โ”‚ + โ”‚ API docs: http://127.0.0.1:8000/docs โ”‚ + โ”‚ โ”‚ + โ”‚ Running in development mode, for production use: โ”‚ + โ”‚ โ”‚ + โ”‚ fastapi run โ”‚ + โ”‚ โ”‚ + โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ + +INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp'] +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +INFO: Started reloader process [2248755] using WatchFiles +INFO: Started server process [2248757] +INFO: Waiting for application startup. +INFO: Application startup complete. +``` + +
+ +
+About the command fastapi dev main.py... + +The command `fastapi dev` reads your `main.py` file, detects the **FastAPI** app in it, and starts a server using Uvicorn. + +By default, `fastapi dev` will start with auto-reload enabled for local development. + +You can read more about it in the FastAPI CLI docs. + +
+ +### Check it + +Open your browser at http://127.0.0.1:8000/items/5?q=somequery. + +You will see the JSON response as: + +```JSON +{"item_id": 5, "q": "somequery"} +``` + +You already created an API that: + +* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`. +* Both _paths_ take `GET` operations (also known as HTTP _methods_). +* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`. +* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`. + +### Interactive API docs + +Now go to http://127.0.0.1:8000/docs. + +You will see the automatic interactive API documentation (provided by Swagger UI): + +![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) + +### Alternative API docs + +And now, go to http://127.0.0.1:8000/redoc. + +You will see the alternative automatic documentation (provided by ReDoc): + +![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) + +## Example upgrade + +Now modify the file `main.py` to receive a body from a `PUT` request. + +Declare the body using standard Python types, thanks to Pydantic. + +```Python hl_lines="4 9-12 25-27" +from typing import Union + +from fastapi import FastAPI +from pydantic import BaseModel + +app = FastAPI() + + +class Item(BaseModel): + name: str + price: float + is_offer: Union[bool, None] = None + + +@app.get("/") +def read_root(): + return {"Hello": "World"} + + +@app.get("/items/{item_id}") +def read_item(item_id: int, q: Union[str, None] = None): + return {"item_id": item_id, "q": q} + + +@app.put("/items/{item_id}") +def update_item(item_id: int, item: Item): + return {"item_name": item.name, "item_id": item_id} +``` + +The `fastapi dev` server should reload automatically. + +### Interactive API docs upgrade + +Now go to http://127.0.0.1:8000/docs. + +* The interactive API documentation will be automatically updated, including the new body: + +![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) + +* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API: + +![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png) + +* Then click on the "Execute" button, the user interface will communicate with your API, send the parameters, get the results and show them on the screen: + +![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png) + +### Alternative API docs upgrade + +And now, go to http://127.0.0.1:8000/redoc. + +* The alternative documentation will also reflect the new query parameter and body: + +![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) + +### Recap + +In summary, you declare **once** the types of parameters, body, etc. as function parameters. + +You do that with standard modern Python types. + +You don't have to learn a new syntax, the methods or classes of a specific library, etc. + +Just standard **Python**. + +For example, for an `int`: + +```Python +item_id: int +``` + +or for a more complex `Item` model: + +```Python +item: Item +``` + +...and with that single declaration you get: + +* Editor support, including: + * Completion. + * Type checks. +* Validation of data: + * Automatic and clear errors when the data is invalid. + * Validation even for deeply nested JSON objects. +* Conversion of input data: coming from the network to Python data and types. Reading from: + * JSON. + * Path parameters. + * Query parameters. + * Cookies. + * Headers. + * Forms. + * Files. +* Conversion of output data: converting from Python data and types to network data (as JSON): + * Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc). + * `datetime` objects. + * `UUID` objects. + * Database models. + * ...and many more. +* Automatic interactive API documentation, including 2 alternative user interfaces: + * Swagger UI. + * ReDoc. + +--- + +Coming back to the previous code example, **FastAPI** will: + +* Validate that there is an `item_id` in the path for `GET` and `PUT` requests. +* Validate that the `item_id` is of type `int` for `GET` and `PUT` requests. + * If it is not, the client will see a useful, clear error. +* Check if there is an optional query parameter named `q` (as in `http://127.0.0.1:8000/items/foo?q=somequery`) for `GET` requests. + * As the `q` parameter is declared with `= None`, it is optional. + * Without the `None` it would be required (as is the body in the case with `PUT`). +* For `PUT` requests to `/items/{item_id}`, read the body as JSON: + * Check that it has a required attribute `name` that should be a `str`. + * Check that it has a required attribute `price` that has to be a `float`. + * Check that it has an optional attribute `is_offer`, that should be a `bool`, if present. + * All this would also work for deeply nested JSON objects. +* Convert from and to JSON automatically. +* Document everything with OpenAPI, that can be used by: + * Interactive documentation systems. + * Automatic client code generation systems, for many languages. +* Provide 2 interactive documentation web interfaces directly. + +--- + +We just scratched the surface, but you already get the idea of how it all works. + +Try changing the line with: + +```Python + return {"item_name": item.name, "item_id": item_id} +``` + +...from: + +```Python + ... "item_name": item.name ... +``` + +...to: + +```Python + ... "item_price": item.price ... +``` + +...and see how your editor will auto-complete the attributes and know their types: + +![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png) + +For a more complete example including more features, see the Tutorial - User Guide. + +**Spoiler alert**: the tutorial - user guide includes: + +* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**. +* How to set **validation constraints** as `maximum_length` or `regex`. +* A very powerful and easy to use **Dependency Injection** system. +* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth. +* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic). +* **GraphQL** integration with Strawberry and other libraries. +* Many extra features (thanks to Starlette) as: + * **WebSockets** + * extremely easy tests based on HTTPX and `pytest` + * **CORS** + * **Cookie Sessions** + * ...and more. + +## Performance + +Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as one of the fastest Python frameworks available, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*) + +To understand more about it, see the section Benchmarks. + +## Dependencies + +FastAPI depends on Pydantic and Starlette. + +### `standard` Dependencies + +When you install FastAPI with `pip install "fastapi[standard]"` it comes with the `standard` group of optional dependencies: + +Used by Pydantic: + +* email-validator - for email validation. + +Used by Starlette: + +* httpx - Required if you want to use the `TestClient`. +* jinja2 - Required if you want to use the default template configuration. +* python-multipart - Required if you want to support form "parsing", with `request.form()`. + +Used by FastAPI / Starlette: + +* uvicorn - for the server that loads and serves your application. This includes `uvicorn[standard]`, which includes some dependencies (e.g. `uvloop`) needed for high performance serving. +* `fastapi-cli` - to provide the `fastapi` command. + +### Without `standard` Dependencies + +If you don't want to include the `standard` optional dependencies, you can install with `pip install fastapi` instead of `pip install "fastapi[standard]"`. + +### Additional Optional Dependencies + +There are some additional dependencies you might want to install. + +Additional optional Pydantic dependencies: + +* pydantic-settings - for settings management. +* pydantic-extra-types - for extra types to be used with Pydantic. + +Additional optional FastAPI dependencies: + +* orjson - Required if you want to use `ORJSONResponse`. +* ujson - Required if you want to use `UJSONResponse`. + +## License + +This project is licensed under the terms of the MIT license. diff --git a/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/RECORD b/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..a535443a62a695a131b198499fd4566ec0d469a1 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/RECORD @@ -0,0 +1,96 @@ +../../../bin/fastapi,sha256=ozVeLQVTLKWi0x-sgvSDSBbpnbxkxT-Or79kovMzyk8,228 +fastapi-0.115.8.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +fastapi-0.115.8.dist-info/METADATA,sha256=4srjIseFlbNIV_5S9uJbfMX9VvUk21nJ_Hu0HnXMqe4,27152 +fastapi-0.115.8.dist-info/RECORD,, +fastapi-0.115.8.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90 +fastapi-0.115.8.dist-info/entry_points.txt,sha256=GCf-WbIZxyGT4MUmrPGj1cOHYZoGsNPHAvNkT6hnGeA,61 +fastapi-0.115.8.dist-info/licenses/LICENSE,sha256=Tsif_IFIW5f-xYSy1KlhAy7v_oNEU4lP2cEnSQbMdE4,1086 +fastapi/__init__.py,sha256=_MYtqtXdcIyUpF2BUpb8Y-6UGaviGakeY05sV25X5DE,1081 +fastapi/__main__.py,sha256=bKePXLdO4SsVSM6r9SVoLickJDcR2c0cTOxZRKq26YQ,37 +fastapi/__pycache__/__init__.cpython-311.pyc,, +fastapi/__pycache__/__main__.cpython-311.pyc,, +fastapi/__pycache__/_compat.cpython-311.pyc,, +fastapi/__pycache__/applications.cpython-311.pyc,, +fastapi/__pycache__/background.cpython-311.pyc,, +fastapi/__pycache__/cli.cpython-311.pyc,, +fastapi/__pycache__/concurrency.cpython-311.pyc,, +fastapi/__pycache__/datastructures.cpython-311.pyc,, +fastapi/__pycache__/encoders.cpython-311.pyc,, +fastapi/__pycache__/exception_handlers.cpython-311.pyc,, +fastapi/__pycache__/exceptions.cpython-311.pyc,, +fastapi/__pycache__/logger.cpython-311.pyc,, +fastapi/__pycache__/param_functions.cpython-311.pyc,, +fastapi/__pycache__/params.cpython-311.pyc,, +fastapi/__pycache__/requests.cpython-311.pyc,, +fastapi/__pycache__/responses.cpython-311.pyc,, +fastapi/__pycache__/routing.cpython-311.pyc,, +fastapi/__pycache__/staticfiles.cpython-311.pyc,, +fastapi/__pycache__/templating.cpython-311.pyc,, +fastapi/__pycache__/testclient.cpython-311.pyc,, +fastapi/__pycache__/types.cpython-311.pyc,, +fastapi/__pycache__/utils.cpython-311.pyc,, +fastapi/__pycache__/websockets.cpython-311.pyc,, +fastapi/_compat.py,sha256=Rg7kA7uue4Z6yr8T7hf8b7G6PeC_06mK004Nnykijfk,23953 +fastapi/applications.py,sha256=Ix-o9pQAWhEDf9J0Q1hZ0nBB1uP72c-Y3oiYzvrwqiM,176316 +fastapi/background.py,sha256=rouLirxUANrcYC824MSMypXL_Qb2HYg2YZqaiEqbEKI,1768 +fastapi/cli.py,sha256=OYhZb0NR_deuT5ofyPF2NoNBzZDNOP8Salef2nk-HqA,418 +fastapi/concurrency.py,sha256=MirfowoSpkMQZ8j_g0ZxaQKpV6eB3G-dB5TgcXCrgEA,1424 +fastapi/datastructures.py,sha256=b2PEz77XGq-u3Ur1Inwk0AGjOsQZO49yF9C7IPJ15cY,5766 +fastapi/dependencies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +fastapi/dependencies/__pycache__/__init__.cpython-311.pyc,, +fastapi/dependencies/__pycache__/models.cpython-311.pyc,, +fastapi/dependencies/__pycache__/utils.cpython-311.pyc,, +fastapi/dependencies/models.py,sha256=Pjl6vx-4nZ5Tta9kJa3-RfQKkXtCpS09-FhMgs9eWNs,1507 +fastapi/dependencies/utils.py,sha256=UqN1H0k_4PCnP-nRYNpup1fdIuzEx1F5ZVO6WuVRx4E,35579 +fastapi/encoders.py,sha256=LvwYmFeOz4tVwvgBoC5rvZnbr7hZr73KGrU8O7zSptU,11068 +fastapi/exception_handlers.py,sha256=MBrIOA-ugjJDivIi4rSsUJBdTsjuzN76q4yh0q1COKw,1332 +fastapi/exceptions.py,sha256=taNixuFEXb67lI1bnX1ubq8y8TseJ4yoPlWjyP0fTzk,4969 +fastapi/logger.py,sha256=I9NNi3ov8AcqbsbC9wl1X-hdItKgYt2XTrx1f99Zpl4,54 +fastapi/middleware/__init__.py,sha256=oQDxiFVcc1fYJUOIFvphnK7pTT5kktmfL32QXpBFvvo,58 +fastapi/middleware/__pycache__/__init__.cpython-311.pyc,, +fastapi/middleware/__pycache__/cors.cpython-311.pyc,, +fastapi/middleware/__pycache__/gzip.cpython-311.pyc,, +fastapi/middleware/__pycache__/httpsredirect.cpython-311.pyc,, +fastapi/middleware/__pycache__/trustedhost.cpython-311.pyc,, +fastapi/middleware/__pycache__/wsgi.cpython-311.pyc,, +fastapi/middleware/cors.py,sha256=ynwjWQZoc_vbhzZ3_ZXceoaSrslHFHPdoM52rXr0WUU,79 +fastapi/middleware/gzip.py,sha256=xM5PcsH8QlAimZw4VDvcmTnqQamslThsfe3CVN2voa0,79 +fastapi/middleware/httpsredirect.py,sha256=rL8eXMnmLijwVkH7_400zHri1AekfeBd6D6qs8ix950,115 +fastapi/middleware/trustedhost.py,sha256=eE5XGRxGa7c5zPnMJDGp3BxaL25k5iVQlhnv-Pk0Pss,109 +fastapi/middleware/wsgi.py,sha256=Z3Ue-7wni4lUZMvH3G9ek__acgYdJstbnpZX_HQAboY,79 +fastapi/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +fastapi/openapi/__pycache__/__init__.cpython-311.pyc,, +fastapi/openapi/__pycache__/constants.cpython-311.pyc,, +fastapi/openapi/__pycache__/docs.cpython-311.pyc,, +fastapi/openapi/__pycache__/models.cpython-311.pyc,, +fastapi/openapi/__pycache__/utils.cpython-311.pyc,, +fastapi/openapi/constants.py,sha256=adGzmis1L1HJRTE3kJ5fmHS_Noq6tIY6pWv_SFzoFDU,153 +fastapi/openapi/docs.py,sha256=XcQq-ZbQdC5sI0gIGu5MoHK1q-OFaqws7-ORTo6sjY4,10348 +fastapi/openapi/models.py,sha256=PqkxQiqcEgjKuhfUIWPZPQcyTcubtUCB3vcObLsB7VE,15397 +fastapi/openapi/utils.py,sha256=vpbAzWpuNaJL_ocBxt4jp0GUUwrDKNB1anyoAx69fhA,23177 +fastapi/param_functions.py,sha256=JHNPLIYvoAwdnZZavIVsxOat8x23fX_Kl33reh7HKl8,64019 +fastapi/params.py,sha256=g450axUBQgQJODdtM7WBxZbQj9Z64inFvadrgHikBbU,28237 +fastapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +fastapi/requests.py,sha256=zayepKFcienBllv3snmWI20Gk0oHNVLU4DDhqXBb4LU,142 +fastapi/responses.py,sha256=QNQQlwpKhQoIPZTTWkpc9d_QGeGZ_aVQPaDV3nQ8m7c,1761 +fastapi/routing.py,sha256=WK06IwZeyRwxkdB4uHZ7JXinxtVOxM8Ke0tqHaDOvYA,176208 +fastapi/security/__init__.py,sha256=bO8pNmxqVRXUjfl2mOKiVZLn0FpBQ61VUYVjmppnbJw,881 +fastapi/security/__pycache__/__init__.cpython-311.pyc,, +fastapi/security/__pycache__/api_key.cpython-311.pyc,, +fastapi/security/__pycache__/base.cpython-311.pyc,, +fastapi/security/__pycache__/http.cpython-311.pyc,, +fastapi/security/__pycache__/oauth2.cpython-311.pyc,, +fastapi/security/__pycache__/open_id_connect_url.cpython-311.pyc,, +fastapi/security/__pycache__/utils.cpython-311.pyc,, +fastapi/security/api_key.py,sha256=cBI5Z4zWVjL1uJrsjTeLy7MafHPAO2HQPzTrpyoIYWA,9094 +fastapi/security/base.py,sha256=dl4pvbC-RxjfbWgPtCWd8MVU-7CB2SZ22rJDXVCXO6c,141 +fastapi/security/http.py,sha256=223bAV_d7NjI57Pzhbd_KlQTYlMyr5MoN1TW80rbxF8,13512 +fastapi/security/oauth2.py,sha256=xCo5j1qpze6CvEuJHIneOI0v2fodGVMpHHVnHpiLfoM,21589 +fastapi/security/open_id_connect_url.py,sha256=8vizZ2tGqEp1ur8SwtVgyHJhGAJ5AqahgcvSpaIioDI,2722 +fastapi/security/utils.py,sha256=bd8T0YM7UQD5ATKucr1bNtAvz_Y3__dVNAv5UebiPvc,293 +fastapi/staticfiles.py,sha256=iirGIt3sdY2QZXd36ijs3Cj-T0FuGFda3cd90kM9Ikw,69 +fastapi/templating.py,sha256=4zsuTWgcjcEainMJFAlW6-gnslm6AgOS1SiiDWfmQxk,76 +fastapi/testclient.py,sha256=nBvaAmX66YldReJNZXPOk1sfuo2Q6hs8bOvIaCep6LQ,66 +fastapi/types.py,sha256=nFb36sK3DSoqoyo7Miwy3meKK5UdFBgkAgLSzQlUVyI,383 +fastapi/utils.py,sha256=y8Bj5ttMaI9tS4D60OUgXqKnktBr99NdYUnHHV9LgoY,7948 +fastapi/websockets.py,sha256=419uncYObEKZG0YcrXscfQQYLSWoE10jqxVMetGdR98,222 diff --git a/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/WHEEL b/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..64b991e898ba046168e0036b1939a69510aa2d77 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: pdm-backend (2.4.3) +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/entry_points.txt b/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/entry_points.txt new file mode 100644 index 0000000000000000000000000000000000000000..b81849e1ef82b793f6f81bb970cdc3cb791f5776 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/entry_points.txt @@ -0,0 +1,5 @@ +[console_scripts] +fastapi = fastapi.cli:main + +[gui_scripts] + diff --git a/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/licenses/LICENSE b/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/licenses/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..3e92463e6bd522a2a21e5f0a80d8089d6c4be20d --- /dev/null +++ b/.venv/lib/python3.11/site-packages/fastapi-0.115.8.dist-info/licenses/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Sebastiรกn Ramรญrez + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/.venv/lib/python3.11/site-packages/grpc_status/__init__.py b/.venv/lib/python3.11/site-packages/grpc_status/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..38fdfc9c5cf23b71d5b71dc40ee1524b6ac8ecc5 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/grpc_status/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2018 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/.venv/lib/python3.11/site-packages/grpc_status/__pycache__/__init__.cpython-311.pyc b/.venv/lib/python3.11/site-packages/grpc_status/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..20c3565f59f2a4d05b4dc415e59b28b4156f8835 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/grpc_status/__pycache__/__init__.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/grpc_status/__pycache__/_async.cpython-311.pyc b/.venv/lib/python3.11/site-packages/grpc_status/__pycache__/_async.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..484d66ecd3aabde7fd118f3fad4e6ea3cc54616e Binary files /dev/null and b/.venv/lib/python3.11/site-packages/grpc_status/__pycache__/_async.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/grpc_status/__pycache__/_common.cpython-311.pyc b/.venv/lib/python3.11/site-packages/grpc_status/__pycache__/_common.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ea7aa750a1a0143cb60c3d73aeb3cabc0c14b785 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/grpc_status/__pycache__/_common.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/grpc_status/__pycache__/rpc_status.cpython-311.pyc b/.venv/lib/python3.11/site-packages/grpc_status/__pycache__/rpc_status.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c543ca86142f6b6a9366b9d39523751cd3da05de Binary files /dev/null and b/.venv/lib/python3.11/site-packages/grpc_status/__pycache__/rpc_status.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/grpc_status/_async.py b/.venv/lib/python3.11/site-packages/grpc_status/_async.py new file mode 100644 index 0000000000000000000000000000000000000000..9f58c8a81f3304618fec7defce0def717b2c0f0a --- /dev/null +++ b/.venv/lib/python3.11/site-packages/grpc_status/_async.py @@ -0,0 +1,58 @@ +# Copyright 2020 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Reference implementation for status mapping in gRPC Python.""" + +from google.rpc import status_pb2 +from grpc.experimental import aio + +from ._common import GRPC_DETAILS_METADATA_KEY +from ._common import code_to_grpc_status_code + + +async def from_call(call: aio.Call): + """Returns a google.rpc.status.Status message from a given grpc.aio.Call. + + This is an EXPERIMENTAL API. + + Args: + call: An grpc.aio.Call instance. + + Returns: + A google.rpc.status.Status message representing the status of the RPC. + """ + code = await call.code() + details = await call.details() + trailing_metadata = await call.trailing_metadata() + if trailing_metadata is None: + return None + for key, value in trailing_metadata: + if key == GRPC_DETAILS_METADATA_KEY: + rich_status = status_pb2.Status.FromString(value) + if code.value[0] != rich_status.code: + raise ValueError( + "Code in Status proto (%s) doesn't match status code (%s)" + % (code_to_grpc_status_code(rich_status.code), code) + ) + if details != rich_status.message: + raise ValueError( + "Message in Status proto (%s) doesn't match status details" + " (%s)" % (rich_status.message, details) + ) + return rich_status + return None + + +__all__ = [ + "from_call", +] diff --git a/.venv/lib/python3.11/site-packages/grpc_status/_common.py b/.venv/lib/python3.11/site-packages/grpc_status/_common.py new file mode 100644 index 0000000000000000000000000000000000000000..66677d849d64756ff8b51ab5bf17c158edf42586 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/grpc_status/_common.py @@ -0,0 +1,27 @@ +# Copyright 2020 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Reference implementation for status mapping in gRPC Python.""" + +import grpc + +_CODE_TO_GRPC_CODE_MAPPING = {x.value[0]: x for x in grpc.StatusCode} + +GRPC_DETAILS_METADATA_KEY = "grpc-status-details-bin" + + +def code_to_grpc_status_code(code): + try: + return _CODE_TO_GRPC_CODE_MAPPING[code] + except KeyError: + raise ValueError("Invalid status code %s" % code) diff --git a/.venv/lib/python3.11/site-packages/grpc_status/rpc_status.py b/.venv/lib/python3.11/site-packages/grpc_status/rpc_status.py new file mode 100644 index 0000000000000000000000000000000000000000..a3f10a8b18f4156c0b4754e62c67caf3d32fbeda --- /dev/null +++ b/.venv/lib/python3.11/site-packages/grpc_status/rpc_status.py @@ -0,0 +1,96 @@ +# Copyright 2018 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Reference implementation for status mapping in gRPC Python.""" + +import collections +import sys + +from google.rpc import status_pb2 +import grpc + +from ._common import GRPC_DETAILS_METADATA_KEY +from ._common import code_to_grpc_status_code + + +class _Status( + collections.namedtuple("_Status", ("code", "details", "trailing_metadata")), + grpc.Status, +): + pass + + +def from_call(call): + """Returns a google.rpc.status.Status message corresponding to a given grpc.Call. + + This is an EXPERIMENTAL API. + + Args: + call: A grpc.Call instance. + + Returns: + A google.rpc.status.Status message representing the status of the RPC. + + Raises: + ValueError: If the gRPC call's code or details are inconsistent with the + status code and message inside of the google.rpc.status.Status. + """ + if call.trailing_metadata() is None: + return None + for key, value in call.trailing_metadata(): + if key == GRPC_DETAILS_METADATA_KEY: + rich_status = status_pb2.Status.FromString(value) + if call.code().value[0] != rich_status.code: + raise ValueError( + "Code in Status proto (%s) doesn't match status code (%s)" + % (code_to_grpc_status_code(rich_status.code), call.code()) + ) + if call.details() != rich_status.message: + raise ValueError( + "Message in Status proto (%s) doesn't match status details" + " (%s)" % (rich_status.message, call.details()) + ) + return rich_status + return None + + +def to_status(status): + """Convert a google.rpc.status.Status message to grpc.Status. + + This is an EXPERIMENTAL API. + + Args: + status: a google.rpc.status.Status message representing the non-OK status + to terminate the RPC with and communicate it to the client. + + Returns: + A grpc.Status instance representing the input google.rpc.status.Status message. + """ + return _Status( + code=code_to_grpc_status_code(status.code), + details=status.message, + trailing_metadata=( + (GRPC_DETAILS_METADATA_KEY, status.SerializeToString()), + ), + ) + + +__all__ = [ + "from_call", + "to_status", +] + +if sys.version_info[0] >= 3 and sys.version_info[1] >= 6: + from . import _async as aio # pylint: disable=unused-import + + __all__.append("aio") diff --git a/.venv/lib/python3.11/site-packages/iniconfig-2.0.0.dist-info/INSTALLER b/.venv/lib/python3.11/site-packages/iniconfig-2.0.0.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/iniconfig-2.0.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.11/site-packages/iniconfig-2.0.0.dist-info/METADATA b/.venv/lib/python3.11/site-packages/iniconfig-2.0.0.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..3ea1e01cb025cbdba070501e90fff9b261f1e556 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/iniconfig-2.0.0.dist-info/METADATA @@ -0,0 +1,80 @@ +Metadata-Version: 2.1 +Name: iniconfig +Version: 2.0.0 +Summary: brain-dead simple config-ini parsing +Project-URL: Homepage, https://github.com/pytest-dev/iniconfig +Author-email: Ronny Pfannschmidt , Holger Krekel +License-Expression: MIT +License-File: LICENSE +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: POSIX +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Topic :: Software Development :: Libraries +Classifier: Topic :: Utilities +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst + +iniconfig: brain-dead simple parsing of ini files +======================================================= + +iniconfig is a small and simple INI-file parser module +having a unique set of features: + +* maintains order of sections and entries +* supports multi-line values with or without line-continuations +* supports "#" comments everywhere +* raises errors with proper line-numbers +* no bells and whistles like automatic substitutions +* iniconfig raises an Error if two sections have the same name. + +If you encounter issues or have feature wishes please report them to: + + https://github.com/RonnyPfannschmidt/iniconfig/issues + +Basic Example +=================================== + +If you have an ini file like this: + +.. code-block:: ini + + # content of example.ini + [section1] # comment + name1=value1 # comment + name1b=value1,value2 # comment + + [section2] + name2= + line1 + line2 + +then you can do: + +.. code-block:: pycon + + >>> import iniconfig + >>> ini = iniconfig.IniConfig("example.ini") + >>> ini['section1']['name1'] # raises KeyError if not exists + 'value1' + >>> ini.get('section1', 'name1b', [], lambda x: x.split(",")) + ['value1', 'value2'] + >>> ini.get('section1', 'notexist', [], lambda x: x.split(",")) + [] + >>> [x.name for x in list(ini)] + ['section1', 'section2'] + >>> list(list(ini)[0].items()) + [('name1', 'value1'), ('name1b', 'value1,value2')] + >>> 'section1' in ini + True + >>> 'inexistendsection' in ini + False diff --git a/.venv/lib/python3.11/site-packages/iniconfig-2.0.0.dist-info/RECORD b/.venv/lib/python3.11/site-packages/iniconfig-2.0.0.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..c7fb2a54a2fafa844e0e9d472c79dd1123c51019 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/iniconfig-2.0.0.dist-info/RECORD @@ -0,0 +1,14 @@ +iniconfig-2.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +iniconfig-2.0.0.dist-info/METADATA,sha256=2KcBd5DEFiZclO-ruP_qzN71qcTL0hNsCw5MCDIPN6I,2599 +iniconfig-2.0.0.dist-info/RECORD,, +iniconfig-2.0.0.dist-info/WHEEL,sha256=hKi7AIIx6qfnsRbr087vpeJnrVUuDokDHZacPPMW7-Y,87 +iniconfig-2.0.0.dist-info/licenses/LICENSE,sha256=KvaAw570k_uCgwNW0dPfGstaBgM8ui3sehniHKp3qGY,1061 +iniconfig/__init__.py,sha256=ALJSNenAgTD7RNj820NggEQuyaZp2QseTCThGJPavk0,5473 +iniconfig/__pycache__/__init__.cpython-311.pyc,, +iniconfig/__pycache__/_parse.cpython-311.pyc,, +iniconfig/__pycache__/_version.cpython-311.pyc,, +iniconfig/__pycache__/exceptions.cpython-311.pyc,, +iniconfig/_parse.py,sha256=OWGLbmE8GjxcoMWTvnGbck1RoNsTm5bt5ficIRZqWJ8,2436 +iniconfig/_version.py,sha256=WM8rOXoL5t25aMQJp4qbU2XP09nrDtmDnrAGhHSk0Wk,160 +iniconfig/exceptions.py,sha256=3V2JS5rndwiYUh84PNYS_1zd8H8IB-Rar81ARAA7E9s,501 +iniconfig/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/.venv/lib/python3.11/site-packages/iniconfig-2.0.0.dist-info/WHEEL b/.venv/lib/python3.11/site-packages/iniconfig-2.0.0.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..8d5c0ceb0888d65a6b0c2e7b2ab5fd81e552ca45 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/iniconfig-2.0.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: hatchling 1.12.2 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/lib/python3.11/site-packages/iniconfig-2.0.0.dist-info/licenses/LICENSE b/.venv/lib/python3.11/site-packages/iniconfig-2.0.0.dist-info/licenses/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..31ecdfb1dbc54fb41999867884dad52a07eac2ca --- /dev/null +++ b/.venv/lib/python3.11/site-packages/iniconfig-2.0.0.dist-info/licenses/LICENSE @@ -0,0 +1,19 @@ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + diff --git a/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/INSTALLER b/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/LICENSE.txt b/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..c37cae49ec77ad6ebb25568c1605f1fee5313cfb --- /dev/null +++ b/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/LICENSE.txt @@ -0,0 +1,28 @@ +Copyright 2007 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/METADATA b/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..6d0348d9dd24ad12541f821b2518bbd557df3655 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/METADATA @@ -0,0 +1,75 @@ +Metadata-Version: 2.3 +Name: Jinja2 +Version: 3.1.5 +Summary: A very fast and expressive template engine. +Maintainer-email: Pallets +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Text Processing :: Markup :: HTML +Classifier: Typing :: Typed +Requires-Dist: MarkupSafe>=2.0 +Requires-Dist: Babel>=2.7 ; extra == "i18n" +Project-URL: Changes, https://jinja.palletsprojects.com/changes/ +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://jinja.palletsprojects.com/ +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Source, https://github.com/pallets/jinja/ +Provides-Extra: i18n + +# Jinja + +Jinja is a fast, expressive, extensible templating engine. Special +placeholders in the template allow writing code similar to Python +syntax. Then the template is passed data to render the final document. + +It includes: + +- Template inheritance and inclusion. +- Define and import macros within templates. +- HTML templates can use autoescaping to prevent XSS from untrusted + user input. +- A sandboxed environment can safely render untrusted templates. +- AsyncIO support for generating templates and calling async + functions. +- I18N support with Babel. +- Templates are compiled to optimized Python code just-in-time and + cached, or can be compiled ahead-of-time. +- Exceptions point to the correct line in templates to make debugging + easier. +- Extensible filters, tests, functions, and even syntax. + +Jinja's philosophy is that while application logic belongs in Python if +possible, it shouldn't make the template designer's job difficult by +restricting functionality too much. + + +## In A Nutshell + +```jinja +{% extends "base.html" %} +{% block title %}Members{% endblock %} +{% block content %} + +{% endblock %} +``` + +## Donate + +The Pallets organization develops and supports Jinja and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, [please +donate today][]. + +[please donate today]: https://palletsprojects.com/donate + diff --git a/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/RECORD b/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..df17048426c8f1dbf257ecdb69cff0c29ce8e23a --- /dev/null +++ b/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/RECORD @@ -0,0 +1,57 @@ +jinja2-3.1.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +jinja2-3.1.5.dist-info/LICENSE.txt,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 +jinja2-3.1.5.dist-info/METADATA,sha256=PJNSUFNBwoqGA2vce2XSP8M_p2EYqAHYI7hoWLABtFo,2593 +jinja2-3.1.5.dist-info/RECORD,, +jinja2-3.1.5.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82 +jinja2-3.1.5.dist-info/entry_points.txt,sha256=OL85gYU1eD8cuPlikifFngXpeBjaxl6rIJ8KkC_3r-I,58 +jinja2/__init__.py,sha256=zpt8UHzpS2eB1c04kn1LkKkaXLXXcKd33klq7UJGIgg,1928 +jinja2/__pycache__/__init__.cpython-311.pyc,, +jinja2/__pycache__/_identifier.cpython-311.pyc,, +jinja2/__pycache__/async_utils.cpython-311.pyc,, +jinja2/__pycache__/bccache.cpython-311.pyc,, +jinja2/__pycache__/compiler.cpython-311.pyc,, +jinja2/__pycache__/constants.cpython-311.pyc,, +jinja2/__pycache__/debug.cpython-311.pyc,, +jinja2/__pycache__/defaults.cpython-311.pyc,, +jinja2/__pycache__/environment.cpython-311.pyc,, +jinja2/__pycache__/exceptions.cpython-311.pyc,, +jinja2/__pycache__/ext.cpython-311.pyc,, +jinja2/__pycache__/filters.cpython-311.pyc,, +jinja2/__pycache__/idtracking.cpython-311.pyc,, +jinja2/__pycache__/lexer.cpython-311.pyc,, +jinja2/__pycache__/loaders.cpython-311.pyc,, +jinja2/__pycache__/meta.cpython-311.pyc,, +jinja2/__pycache__/nativetypes.cpython-311.pyc,, +jinja2/__pycache__/nodes.cpython-311.pyc,, +jinja2/__pycache__/optimizer.cpython-311.pyc,, +jinja2/__pycache__/parser.cpython-311.pyc,, +jinja2/__pycache__/runtime.cpython-311.pyc,, +jinja2/__pycache__/sandbox.cpython-311.pyc,, +jinja2/__pycache__/tests.cpython-311.pyc,, +jinja2/__pycache__/utils.cpython-311.pyc,, +jinja2/__pycache__/visitor.cpython-311.pyc,, +jinja2/_identifier.py,sha256=_zYctNKzRqlk_murTNlzrju1FFJL7Va_Ijqqd7ii2lU,1958 +jinja2/async_utils.py,sha256=vK-PdsuorOMnWSnEkT3iUJRIkTnYgO2T6MnGxDgHI5o,2834 +jinja2/bccache.py,sha256=gh0qs9rulnXo0PhX5jTJy2UHzI8wFnQ63o_vw7nhzRg,14061 +jinja2/compiler.py,sha256=9RpCQl5X88BHllJiPsHPh295Hh0uApvwFJNQuutULeM,74131 +jinja2/constants.py,sha256=GMoFydBF_kdpaRKPoM5cl5MviquVRLVyZtfp5-16jg0,1433 +jinja2/debug.py,sha256=CnHqCDHd-BVGvti_8ZsTolnXNhA3ECsY-6n_2pwU8Hw,6297 +jinja2/defaults.py,sha256=boBcSw78h-lp20YbaXSJsqkAI2uN_mD_TtCydpeq5wU,1267 +jinja2/environment.py,sha256=9nhrP7Ch-NbGX00wvyr4yy-uhNHq2OCc60ggGrni_fk,61513 +jinja2/exceptions.py,sha256=ioHeHrWwCWNaXX1inHmHVblvc4haO7AXsjCp3GfWvx0,5071 +jinja2/ext.py,sha256=5PF5eHfh8mXAIxXHHRB2xXbXohi8pE3nHSOxa66uS7E,31875 +jinja2/filters.py,sha256=cvRI2pqXNMzw8ba41VOBpgu_wu1r-l1_QxwD6yVoJ5g,55025 +jinja2/idtracking.py,sha256=-ll5lIp73pML3ErUYiIJj7tdmWxcH_IlDv3yA_hiZYo,10555 +jinja2/lexer.py,sha256=LYiYio6br-Tep9nPcupWXsPEtjluw3p1mU-lNBVRUfk,29786 +jinja2/loaders.py,sha256=wIrnxjvcbqh5VwW28NSkfotiDq8qNCxIOSFbGUiSLB4,24055 +jinja2/meta.py,sha256=OTDPkaFvU2Hgvx-6akz7154F8BIWaRmvJcBFvwopHww,4397 +jinja2/nativetypes.py,sha256=7GIGALVJgdyL80oZJdQUaUfwSt5q2lSSZbXt0dNf_M4,4210 +jinja2/nodes.py,sha256=m1Duzcr6qhZI8JQ6VyJgUNinjAf5bQzijSmDnMsvUx8,34579 +jinja2/optimizer.py,sha256=rJnCRlQ7pZsEEmMhsQDgC_pKyDHxP5TPS6zVPGsgcu8,1651 +jinja2/parser.py,sha256=lLOFy3sEmHc5IaEHRiH1sQVnId2moUQzhyeJZTtdY30,40383 +jinja2/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +jinja2/runtime.py,sha256=gDk-GvdriJXqgsGbHgrcKTP0Yp6zPXzhzrIpCFH3jAU,34249 +jinja2/sandbox.py,sha256=Mw2aitlY2I8la7FYhcX2YG9BtUYcLnD0Gh3d29cDWrY,15009 +jinja2/tests.py,sha256=VLsBhVFnWg-PxSBz1MhRnNWgP1ovXk3neO1FLQMeC9Q,5926 +jinja2/utils.py,sha256=rRp3o9e7ZKS4fyrWRbELyLcpuGVTFcnooaOa1qx_FIk,24129 +jinja2/visitor.py,sha256=EcnL1PIwf_4RVCOMxsRNuR8AXHbS1qfAdMOE2ngKJz4,3557 diff --git a/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/WHEEL b/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..e3c6feefa22927866e3fd5575379ea972b432aaf --- /dev/null +++ b/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.10.1 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/entry_points.txt b/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/entry_points.txt new file mode 100644 index 0000000000000000000000000000000000000000..abc3eae3b3bc573957cf7401711948799b3465c0 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[babel.extractors] +jinja2=jinja2.ext:babel_extract[i18n] + diff --git a/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/INSTALLER b/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/License.txt b/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/License.txt new file mode 100644 index 0000000000000000000000000000000000000000..b491c70e0aef319022ded661e111ddbd45b8a17f --- /dev/null +++ b/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/License.txt @@ -0,0 +1,1568 @@ +End User License Agreement +-------------------------- + + +Preface +------- + +The Software License Agreement in Chapter 1 and the Supplement +in Chapter 2 contain license terms and conditions that govern +the use of NVIDIA software. By accepting this agreement, you +agree to comply with all the terms and conditions applicable +to the product(s) included herein. + + +NVIDIA Driver + + +Description + +This package contains the operating system driver and +fundamental system software components for NVIDIA GPUs. + + +NVIDIA CUDA Toolkit + + +Description + +The NVIDIA CUDA Toolkit provides command-line and graphical +tools for building, debugging and optimizing the performance +of applications accelerated by NVIDIA GPUs, runtime and math +libraries, and documentation including programming guides, +user manuals, and API references. + + +Default Install Location of CUDA Toolkit + +Windows platform: + +%ProgramFiles%\NVIDIA GPU Computing Toolkit\CUDA\v#.# + +Linux platform: + +/usr/local/cuda-#.# + +Mac platform: + +/Developer/NVIDIA/CUDA-#.# + + +NVIDIA CUDA Samples + + +Description + +This package includes over 100+ CUDA examples that demonstrate +various CUDA programming principles, and efficient CUDA +implementation of algorithms in specific application domains. + + +Default Install Location of CUDA Samples + +Windows platform: + +%ProgramData%\NVIDIA Corporation\CUDA Samples\v#.# + +Linux platform: + +/usr/local/cuda-#.#/samples + +and + +$HOME/NVIDIA_CUDA-#.#_Samples + +Mac platform: + +/Developer/NVIDIA/CUDA-#.#/samples + + +NVIDIA Nsight Visual Studio Edition (Windows only) + + +Description + +NVIDIA Nsight Development Platform, Visual Studio Edition is a +development environment integrated into Microsoft Visual +Studio that provides tools for debugging, profiling, analyzing +and optimizing your GPU computing and graphics applications. + + +Default Install Location of Nsight Visual Studio Edition + +Windows platform: + +%ProgramFiles(x86)%\NVIDIA Corporation\Nsight Visual Studio Edition #.# + + +1. License Agreement for NVIDIA Software Development Kits +--------------------------------------------------------- + + +Release Date: July 26, 2018 +--------------------------- + + +Important NoticeRead before downloading, installing, +copying or using the licensed software: +------------------------------------------------------- + +This license agreement, including exhibits attached +("Agreementโ€) is a legal agreement between you and NVIDIA +Corporation ("NVIDIA") and governs your use of a NVIDIA +software development kit (โ€œSDKโ€). + +Each SDK has its own set of software and materials, but here +is a description of the types of items that may be included in +a SDK: source code, header files, APIs, data sets and assets +(examples include images, textures, models, scenes, videos, +native API input/output files), binary software, sample code, +libraries, utility programs, programming code and +documentation. + +This Agreement can be accepted only by an adult of legal age +of majority in the country in which the SDK is used. + +If you are entering into this Agreement on behalf of a company +or other legal entity, you represent that you have the legal +authority to bind the entity to this Agreement, in which case +โ€œyouโ€ will mean the entity you represent. + +If you donโ€™t have the required age or authority to accept +this Agreement, or if you donโ€™t accept all the terms and +conditions of this Agreement, do not download, install or use +the SDK. + +You agree to use the SDK only for purposes that are permitted +by (a) this Agreement, and (b) any applicable law, regulation +or generally accepted practices or guidelines in the relevant +jurisdictions. + + +1.1. License + + +1.1.1. License Grant + +Subject to the terms of this Agreement, NVIDIA hereby grants +you a non-exclusive, non-transferable license, without the +right to sublicense (except as expressly provided in this +Agreement) to: + + 1. Install and use the SDK, + + 2. Modify and create derivative works of sample source code + delivered in the SDK, and + + 3. Distribute those portions of the SDK that are identified + in this Agreement as distributable, as incorporated in + object code format into a software application that meets + the distribution requirements indicated in this Agreement. + + +1.1.2. Distribution Requirements + +These are the distribution requirements for you to exercise +the distribution grant: + + 1. Your application must have material additional + functionality, beyond the included portions of the SDK. + + 2. The distributable portions of the SDK shall only be + accessed by your application. + + 3. The following notice shall be included in modifications + and derivative works of sample source code distributed: + โ€œThis software contains source code provided by NVIDIA + Corporation.โ€ + + 4. Unless a developer tool is identified in this Agreement + as distributable, it is delivered for your internal use + only. + + 5. The terms under which you distribute your application + must be consistent with the terms of this Agreement, + including (without limitation) terms relating to the + license grant and license restrictions and protection of + NVIDIAโ€™s intellectual property rights. Additionally, you + agree that you will protect the privacy, security and + legal rights of your application users. + + 6. You agree to notify NVIDIA in writing of any known or + suspected distribution or use of the SDK not in compliance + with the requirements of this Agreement, and to enforce + the terms of your agreements with respect to distributed + SDK. + + +1.1.3. Authorized Users + +You may allow employees and contractors of your entity or of +your subsidiary(ies) to access and use the SDK from your +secure network to perform work on your behalf. + +If you are an academic institution you may allow users +enrolled or employed by the academic institution to access and +use the SDK from your secure network. + +You are responsible for the compliance with the terms of this +Agreement by your authorized users. If you become aware that +your authorized users didnโ€™t follow the terms of this +Agreement, you agree to take reasonable steps to resolve the +non-compliance and prevent new occurrences. + + +1.1.4. Pre-Release SDK + +The SDK versions identified as alpha, beta, preview or +otherwise as pre-release, may not be fully functional, may +contain errors or design flaws, and may have reduced or +different security, privacy, accessibility, availability, and +reliability standards relative to commercial versions of +NVIDIA software and materials. Use of a pre-release SDK may +result in unexpected results, loss of data, project delays or +other unpredictable damage or loss. + +You may use a pre-release SDK at your own risk, understanding +that pre-release SDKs are not intended for use in production +or business-critical systems. + +NVIDIA may choose not to make available a commercial version +of any pre-release SDK. NVIDIA may also choose to abandon +development and terminate the availability of a pre-release +SDK at any time without liability. + + +1.1.5. Updates + +NVIDIA may, at its option, make available patches, workarounds +or other updates to this SDK. Unless the updates are provided +with their separate governing terms, they are deemed part of +the SDK licensed to you as provided in this Agreement. You +agree that the form and content of the SDK that NVIDIA +provides may change without prior notice to you. While NVIDIA +generally maintains compatibility between versions, NVIDIA may +in some cases make changes that introduce incompatibilities in +future versions of the SDK. + + +1.1.6. Third Party Licenses + +The SDK may come bundled with, or otherwise include or be +distributed with, third party software licensed by a NVIDIA +supplier and/or open source software provided under an open +source license. Use of third party software is subject to the +third-party license terms, or in the absence of third party +terms, the terms of this Agreement. Copyright to third party +software is held by the copyright holders indicated in the +third-party software or license. + + +1.1.7. Reservation of Rights + +NVIDIA reserves all rights, title, and interest in and to the +SDK, not expressly granted to you under this Agreement. + + +1.2. Limitations + +The following license limitations apply to your use of the +SDK: + + 1. You may not reverse engineer, decompile or disassemble, + or remove copyright or other proprietary notices from any + portion of the SDK or copies of the SDK. + + 2. Except as expressly provided in this Agreement, you may + not copy, sell, rent, sublicense, transfer, distribute, + modify, or create derivative works of any portion of the + SDK. For clarity, you may not distribute or sublicense the + SDK as a stand-alone product. + + 3. Unless you have an agreement with NVIDIA for this + purpose, you may not indicate that an application created + with the SDK is sponsored or endorsed by NVIDIA. + + 4. You may not bypass, disable, or circumvent any + encryption, security, digital rights management or + authentication mechanism in the SDK. + + 5. You may not use the SDK in any manner that would cause it + to become subject to an open source software license. As + examples, licenses that require as a condition of use, + modification, and/or distribution that the SDK be: + + a. Disclosed or distributed in source code form; + + b. Licensed for the purpose of making derivative works; + or + + c. Redistributable at no charge. + + 6. Unless you have an agreement with NVIDIA for this + purpose, you may not use the SDK with any system or + application where the use or failure of the system or + application can reasonably be expected to threaten or + result in personal injury, death, or catastrophic loss. + Examples include use in avionics, navigation, military, + medical, life support or other life critical applications. + NVIDIA does not design, test or manufacture the SDK for + these critical uses and NVIDIA shall not be liable to you + or any third party, in whole or in part, for any claims or + damages arising from such uses. + + 7. You agree to defend, indemnify and hold harmless NVIDIA + and its affiliates, and their respective employees, + contractors, agents, officers and directors, from and + against any and all claims, damages, obligations, losses, + liabilities, costs or debt, fines, restitutions and + expenses (including but not limited to attorneyโ€™s fees + and costs incident to establishing the right of + indemnification) arising out of or related to your use of + the SDK outside of the scope of this Agreement, or not in + compliance with its terms. + + +1.3. Ownership + + 1. NVIDIA or its licensors hold all rights, title and + interest in and to the SDK and its modifications and + derivative works, including their respective intellectual + property rights, subject to your rights described in this + section. This SDK may include software and materials from + NVIDIAโ€™s licensors, and these licensors are intended + third party beneficiaries that may enforce this Agreement + with respect to their intellectual property rights. + + 2. You hold all rights, title and interest in and to your + applications and your derivative works of the sample + source code delivered in the SDK, including their + respective intellectual property rights, subject to + NVIDIAโ€™s rights described in this section. + + 3. You may, but donโ€™t have to, provide to NVIDIA + suggestions, feature requests or other feedback regarding + the SDK, including possible enhancements or modifications + to the SDK. For any feedback that you voluntarily provide, + you hereby grant NVIDIA and its affiliates a perpetual, + non-exclusive, worldwide, irrevocable license to use, + reproduce, modify, license, sublicense (through multiple + tiers of sublicensees), and distribute (through multiple + tiers of distributors) it without the payment of any + royalties or fees to you. NVIDIA will use feedback at its + choice. NVIDIA is constantly looking for ways to improve + its products, so you may send feedback to NVIDIA through + the developer portal at https://developer.nvidia.com. + + +1.4. No Warranties + +THE SDK IS PROVIDED BY NVIDIA โ€œAS ISโ€ AND โ€œWITH ALL +FAULTS.โ€ TO THE MAXIMUM EXTENT PERMITTED BY LAW, NVIDIA AND +ITS AFFILIATES EXPRESSLY DISCLAIM ALL WARRANTIES OF ANY KIND +OR NATURE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, +BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE, TITLE, NON-INFRINGEMENT, OR THE +ABSENCE OF ANY DEFECTS THEREIN, WHETHER LATENT OR PATENT. NO +WARRANTY IS MADE ON THE BASIS OF TRADE USAGE, COURSE OF +DEALING OR COURSE OF TRADE. + + +1.5. Limitation of Liability + +TO THE MAXIMUM EXTENT PERMITTED BY LAW, NVIDIA AND ITS +AFFILIATES SHALL NOT BE LIABLE FOR ANY SPECIAL, INCIDENTAL, +PUNITIVE OR CONSEQUENTIAL DAMAGES, OR ANY LOST PROFITS, LOSS +OF USE, LOSS OF DATA OR LOSS OF GOODWILL, OR THE COSTS OF +PROCURING SUBSTITUTE PRODUCTS, ARISING OUT OF OR IN CONNECTION +WITH THIS AGREEMENT OR THE USE OR PERFORMANCE OF THE SDK, +WHETHER SUCH LIABILITY ARISES FROM ANY CLAIM BASED UPON BREACH +OF CONTRACT, BREACH OF WARRANTY, TORT (INCLUDING NEGLIGENCE), +PRODUCT LIABILITY OR ANY OTHER CAUSE OF ACTION OR THEORY OF +LIABILITY. IN NO EVENT WILL NVIDIAโ€™S AND ITS AFFILIATES +TOTAL CUMULATIVE LIABILITY UNDER OR ARISING OUT OF THIS +AGREEMENT EXCEED US$10.00. THE NATURE OF THE LIABILITY OR THE +NUMBER OF CLAIMS OR SUITS SHALL NOT ENLARGE OR EXTEND THIS +LIMIT. + +These exclusions and limitations of liability shall apply +regardless if NVIDIA or its affiliates have been advised of +the possibility of such damages, and regardless of whether a +remedy fails its essential purpose. These exclusions and +limitations of liability form an essential basis of the +bargain between the parties, and, absent any of these +exclusions or limitations of liability, the provisions of this +Agreement, including, without limitation, the economic terms, +would be substantially different. + + +1.6. Termination + + 1. This Agreement will continue to apply until terminated by + either you or NVIDIA as described below. + + 2. If you want to terminate this Agreement, you may do so by + stopping to use the SDK. + + 3. NVIDIA may, at any time, terminate this Agreement if: + + a. (i) you fail to comply with any term of this + Agreement and the non-compliance is not fixed within + thirty (30) days following notice from NVIDIA (or + immediately if you violate NVIDIAโ€™s intellectual + property rights); + + b. (ii) you commence or participate in any legal + proceeding against NVIDIA with respect to the SDK; or + + c. (iii) NVIDIA decides to no longer provide the SDK in + a country or, in NVIDIAโ€™s sole discretion, the + continued use of it is no longer commercially viable. + + 4. Upon any termination of this Agreement, you agree to + promptly discontinue use of the SDK and destroy all copies + in your possession or control. Your prior distributions in + accordance with this Agreement are not affected by the + termination of this Agreement. Upon written request, you + will certify in writing that you have complied with your + commitments under this section. Upon any termination of + this Agreement all provisions survive except for the + license grant provisions. + + +1.7. General + +If you wish to assign this Agreement or your rights and +obligations, including by merger, consolidation, dissolution +or operation of law, contact NVIDIA to ask for permission. Any +attempted assignment not approved by NVIDIA in writing shall +be void and of no effect. NVIDIA may assign, delegate or +transfer this Agreement and its rights and obligations, and if +to a non-affiliate you will be notified. + +You agree to cooperate with NVIDIA and provide reasonably +requested information to verify your compliance with this +Agreement. + +This Agreement will be governed in all respects by the laws of +the United States and of the State of Delaware as those laws +are applied to contracts entered into and performed entirely +within Delaware by Delaware residents, without regard to the +conflicts of laws principles. The United Nations Convention on +Contracts for the International Sale of Goods is specifically +disclaimed. You agree to all terms of this Agreement in the +English language. + +The state or federal courts residing in Santa Clara County, +California shall have exclusive jurisdiction over any dispute +or claim arising out of this Agreement. Notwithstanding this, +you agree that NVIDIA shall still be allowed to apply for +injunctive remedies or an equivalent type of urgent legal +relief in any jurisdiction. + +If any court of competent jurisdiction determines that any +provision of this Agreement is illegal, invalid or +unenforceable, such provision will be construed as limited to +the extent necessary to be consistent with and fully +enforceable under the law and the remaining provisions will +remain in full force and effect. Unless otherwise specified, +remedies are cumulative. + +Each party acknowledges and agrees that the other is an +independent contractor in the performance of this Agreement. + +The SDK has been developed entirely at private expense and is +โ€œcommercial itemsโ€ consisting of โ€œcommercial computer +softwareโ€ and โ€œcommercial computer software +documentationโ€ provided with RESTRICTED RIGHTS. Use, +duplication or disclosure by the U.S. Government or a U.S. +Government subcontractor is subject to the restrictions in +this Agreement pursuant to DFARS 227.7202-3(a) or as set forth +in subparagraphs (c)(1) and (2) of the Commercial Computer +Software - Restricted Rights clause at FAR 52.227-19, as +applicable. Contractor/manufacturer is NVIDIA, 2788 San Tomas +Expressway, Santa Clara, CA 95051. + +The SDK is subject to United States export laws and +regulations. You agree that you will not ship, transfer or +export the SDK into any country, or use the SDK in any manner, +prohibited by the United States Bureau of Industry and +Security or economic sanctions regulations administered by the +U.S. Department of Treasuryโ€™s Office of Foreign Assets +Control (OFAC), or any applicable export laws, restrictions or +regulations. These laws include restrictions on destinations, +end users and end use. By accepting this Agreement, you +confirm that you are not a resident or citizen of any country +currently embargoed by the U.S. and that you are not otherwise +prohibited from receiving the SDK. + +Any notice delivered by NVIDIA to you under this Agreement +will be delivered via mail, email or fax. You agree that any +notices that NVIDIA sends you electronically will satisfy any +legal communication requirements. Please direct your legal +notices or other correspondence to NVIDIA Corporation, 2788 +San Tomas Expressway, Santa Clara, California 95051, United +States of America, Attention: Legal Department. + +This Agreement and any exhibits incorporated into this +Agreement constitute the entire agreement of the parties with +respect to the subject matter of this Agreement and supersede +all prior negotiations or documentation exchanged between the +parties relating to this SDK license. Any additional and/or +conflicting terms on documents issued by you are null, void, +and invalid. Any amendment or waiver under this Agreement +shall be in writing and signed by representatives of both +parties. + + +2. CUDA Toolkit Supplement to Software License Agreement for +NVIDIA Software Development Kits +------------------------------------------------------------ + + +Release date: August 16, 2018 +----------------------------- + +The terms in this supplement govern your use of the NVIDIA +CUDA Toolkit SDK under the terms of your license agreement +(โ€œAgreementโ€) as modified by this supplement. Capitalized +terms used but not defined below have the meaning assigned to +them in the Agreement. + +This supplement is an exhibit to the Agreement and is +incorporated as an integral part of the Agreement. In the +event of conflict between the terms in this supplement and the +terms in the Agreement, the terms in this supplement govern. + + +2.1. License Scope + +The SDK is licensed for you to develop applications only for +use in systems with NVIDIA GPUs. + + +2.2. Distribution + +The portions of the SDK that are distributable under the +Agreement are listed in Attachment A. + + +2.3. Operating Systems + +Those portions of the SDK designed exclusively for use on the +Linux or FreeBSD operating systems, or other operating systems +derived from the source code to these operating systems, may +be copied and redistributed for use in accordance with this +Agreement, provided that the object code files are not +modified in any way (except for unzipping of compressed +files). + + +2.4. Audio and Video Encoders and Decoders + +You acknowledge and agree that it is your sole responsibility +to obtain any additional third-party licenses required to +make, have made, use, have used, sell, import, and offer for +sale your products or services that include or incorporate any +third-party software and content relating to audio and/or +video encoders and decoders from, including but not limited +to, Microsoft, Thomson, Fraunhofer IIS, Sisvel S.p.A., +MPEG-LA, and Coding Technologies. NVIDIA does not grant to you +under this Agreement any necessary patent or other rights with +respect to any audio and/or video encoders and decoders. + + +2.5. Licensing + +If the distribution terms in this Agreement are not suitable +for your organization, or for any questions regarding this +Agreement, please contact NVIDIA at +nvidia-compute-license-questions@nvidia.com. + + +2.6. Attachment A + +The following portions of the SDK are distributable under the +Agreement: + +Component + +CUDA Runtime + +Windows + +cudart.dll, cudart_static.lib, cudadevrt.lib + +Mac OSX + +libcudart.dylib, libcudart_static.a, libcudadevrt.a + +Linux + +libcudart.so, libcudart_static.a, libcudadevrt.a + +Android + +libcudart.so, libcudart_static.a, libcudadevrt.a + +Component + +CUDA FFT Library + +Windows + +cufft.dll, cufftw.dll, cufft.lib, cufftw.lib + +Mac OSX + +libcufft.dylib, libcufft_static.a, libcufftw.dylib, +libcufftw_static.a + +Linux + +libcufft.so, libcufft_static.a, libcufftw.so, +libcufftw_static.a + +Android + +libcufft.so, libcufft_static.a, libcufftw.so, +libcufftw_static.a + +Component + +CUDA BLAS Library + +Windows + +cublas.dll, cublasLt.dll + +Mac OSX + +libcublas.dylib, libcublasLt.dylib, libcublas_static.a, +libcublasLt_static.a + +Linux + +libcublas.so, libcublasLt.so, libcublas_static.a, +libcublasLt_static.a + +Android + +libcublas.so, libcublasLt.so, libcublas_static.a, +libcublasLt_static.a + +Component + +NVIDIA "Drop-in" BLAS Library + +Windows + +nvblas.dll + +Mac OSX + +libnvblas.dylib + +Linux + +libnvblas.so + +Component + +CUDA Sparse Matrix Library + +Windows + +cusparse.dll, cusparse.lib + +Mac OSX + +libcusparse.dylib, libcusparse_static.a + +Linux + +libcusparse.so, libcusparse_static.a + +Android + +libcusparse.so, libcusparse_static.a + +Component + +CUDA Linear Solver Library + +Windows + +cusolver.dll, cusolver.lib + +Mac OSX + +libcusolver.dylib, libcusolver_static.a + +Linux + +libcusolver.so, libcusolver_static.a + +Android + +libcusolver.so, libcusolver_static.a + +Component + +CUDA Random Number Generation Library + +Windows + +curand.dll, curand.lib + +Mac OSX + +libcurand.dylib, libcurand_static.a + +Linux + +libcurand.so, libcurand_static.a + +Android + +libcurand.so, libcurand_static.a + +Component + +CUDA Accelerated Graph Library + +Component + +NVIDIA Performance Primitives Library + +Windows + +nppc.dll, nppc.lib, nppial.dll, nppial.lib, nppicc.dll, +nppicc.lib, nppicom.dll, nppicom.lib, nppidei.dll, +nppidei.lib, nppif.dll, nppif.lib, nppig.dll, nppig.lib, +nppim.dll, nppim.lib, nppist.dll, nppist.lib, nppisu.dll, +nppisu.lib, nppitc.dll, nppitc.lib, npps.dll, npps.lib + +Mac OSX + +libnppc.dylib, libnppc_static.a, libnppial.dylib, +libnppial_static.a, libnppicc.dylib, libnppicc_static.a, +libnppicom.dylib, libnppicom_static.a, libnppidei.dylib, +libnppidei_static.a, libnppif.dylib, libnppif_static.a, +libnppig.dylib, libnppig_static.a, libnppim.dylib, +libnppisu_static.a, libnppitc.dylib, libnppitc_static.a, +libnpps.dylib, libnpps_static.a + +Linux + +libnppc.so, libnppc_static.a, libnppial.so, +libnppial_static.a, libnppicc.so, libnppicc_static.a, +libnppicom.so, libnppicom_static.a, libnppidei.so, +libnppidei_static.a, libnppif.so, libnppif_static.a +libnppig.so, libnppig_static.a, libnppim.so, +libnppim_static.a, libnppist.so, libnppist_static.a, +libnppisu.so, libnppisu_static.a, libnppitc.so +libnppitc_static.a, libnpps.so, libnpps_static.a + +Android + +libnppc.so, libnppc_static.a, libnppial.so, +libnppial_static.a, libnppicc.so, libnppicc_static.a, +libnppicom.so, libnppicom_static.a, libnppidei.so, +libnppidei_static.a, libnppif.so, libnppif_static.a +libnppig.so, libnppig_static.a, libnppim.so, +libnppim_static.a, libnppist.so, libnppist_static.a, +libnppisu.so, libnppisu_static.a, libnppitc.so +libnppitc_static.a, libnpps.so, libnpps_static.a + +Component + +NVIDIA JPEG Library + +Linux + +libnvjpeg.so, libnvjpeg_static.a + +Component + +Internal common library required for statically linking to +cuBLAS, cuSPARSE, cuFFT, cuRAND, nvJPEG and NPP + +Mac OSX + +libculibos.a + +Linux + +libculibos.a + +Component + +NVIDIA Runtime Compilation Library and Header + +All + +nvrtc.h + +Windows + +nvrtc.dll, nvrtc-builtins.dll + +Mac OSX + +libnvrtc.dylib, libnvrtc-builtins.dylib + +Linux + +libnvrtc.so, libnvrtc-builtins.so + +Component + +NVIDIA Optimizing Compiler Library + +Windows + +nvvm.dll + +Mac OSX + +libnvvm.dylib + +Linux + +libnvvm.so + +Component + +NVIDIA Common Device Math Functions Library + +Windows + +libdevice.10.bc + +Mac OSX + +libdevice.10.bc + +Linux + +libdevice.10.bc + +Component + +CUDA Occupancy Calculation Header Library + +All + +cuda_occupancy.h + +Component + +CUDA Half Precision Headers + +All + +cuda_fp16.h, cuda_fp16.hpp + +Component + +CUDA Profiling Tools Interface (CUPTI) Library + +Windows + +cupti.dll + +Mac OSX + +libcupti.dylib + +Linux + +libcupti.so + +Component + +NVIDIA Tools Extension Library + +Windows + +nvToolsExt.dll, nvToolsExt.lib + +Mac OSX + +libnvToolsExt.dylib + +Linux + +libnvToolsExt.so + +Component + +NVIDIA CUDA Driver Libraries + +Linux + +libcuda.so, libnvidia-fatbinaryloader.so, +libnvidia-ptxjitcompiler.so + +The NVIDIA CUDA Driver Libraries are only distributable in +applications that meet this criteria: + + 1. The application was developed starting from a NVIDIA CUDA + container obtained from Docker Hub or the NVIDIA GPU + Cloud, and + + 2. The resulting application is packaged as a Docker + container and distributed to users on Docker Hub or the + NVIDIA GPU Cloud only. + + +2.7. Attachment B + + +Additional Licensing Obligations + +The following third party components included in the SOFTWARE +are licensed to Licensee pursuant to the following terms and +conditions: + + 1. Licensee's use of the GDB third party component is + subject to the terms and conditions of GNU GPL v3: + + This product includes copyrighted third-party software licensed + under the terms of the GNU General Public License v3 ("GPL v3"). + All third-party software packages are copyright by their respective + authors. GPL v3 terms and conditions are hereby incorporated into + the Agreement by this reference: http://www.gnu.org/licenses/gpl.txt + + Consistent with these licensing requirements, the software + listed below is provided under the terms of the specified + open source software licenses. To obtain source code for + software provided under licenses that require + redistribution of source code, including the GNU General + Public License (GPL) and GNU Lesser General Public License + (LGPL), contact oss-requests@nvidia.com. This offer is + valid for a period of three (3) years from the date of the + distribution of this product by NVIDIA CORPORATION. + + Component License + CUDA-GDB GPL v3 + + 2. Licensee represents and warrants that any and all third + party licensing and/or royalty payment obligations in + connection with Licensee's use of the H.264 video codecs + are solely the responsibility of Licensee. + + 3. Licensee's use of the Thrust library is subject to the + terms and conditions of the Apache License Version 2.0. + All third-party software packages are copyright by their + respective authors. Apache License Version 2.0 terms and + conditions are hereby incorporated into the Agreement by + this reference. + http://www.apache.org/licenses/LICENSE-2.0.html + + In addition, Licensee acknowledges the following notice: + Thrust includes source code from the Boost Iterator, + Tuple, System, and Random Number libraries. + + Boost Software License - Version 1.0 - August 17th, 2003 + . . . . + + Permission is hereby granted, free of charge, to any person or + organization obtaining a copy of the software and accompanying + documentation covered by this license (the "Software") to use, + reproduce, display, distribute, execute, and transmit the Software, + and to prepare derivative works of the Software, and to permit + third-parties to whom the Software is furnished to do so, all + subject to the following: + + The copyright notices in the Software and this entire statement, + including the above license grant, this restriction and the following + disclaimer, must be included in all copies of the Software, in whole + or in part, and all derivative works of the Software, unless such + copies or derivative works are solely in the form of machine-executable + object code generated by a source language processor. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR + OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + 4. Licensee's use of the LLVM third party component is + subject to the following terms and conditions: + + ====================================================== + LLVM Release License + ====================================================== + University of Illinois/NCSA + Open Source License + + Copyright (c) 2003-2010 University of Illinois at Urbana-Champaign. + All rights reserved. + + Developed by: + + LLVM Team + + University of Illinois at Urbana-Champaign + + http://llvm.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal with the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the LLVM Team, University of Illinois at Urbana- + Champaign, nor the names of its contributors may be used to endorse or + promote products derived from this Software without specific prior + written permission. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS WITH THE SOFTWARE. + + 5. Licensee's use (e.g. nvprof) of the PCRE third party + component is subject to the following terms and + conditions: + + ------------ + PCRE LICENCE + ------------ + PCRE is a library of functions to support regular expressions whose syntax + and semantics are as close as possible to those of the Perl 5 language. + Release 8 of PCRE is distributed under the terms of the "BSD" licence, as + specified below. The documentation for PCRE, supplied in the "doc" + directory, is distributed under the same terms as the software itself. The + basic library functions are written in C and are freestanding. Also + included in the distribution is a set of C++ wrapper functions, and a just- + in-time compiler that can be used to optimize pattern matching. These are + both optional features that can be omitted when the library is built. + + THE BASIC LIBRARY FUNCTIONS + --------------------------- + Written by: Philip Hazel + Email local part: ph10 + Email domain: cam.ac.uk + University of Cambridge Computing Service, + Cambridge, England. + Copyright (c) 1997-2012 University of Cambridge + All rights reserved. + + PCRE JUST-IN-TIME COMPILATION SUPPORT + ------------------------------------- + Written by: Zoltan Herczeg + Email local part: hzmester + Emain domain: freemail.hu + Copyright(c) 2010-2012 Zoltan Herczeg + All rights reserved. + + STACK-LESS JUST-IN-TIME COMPILER + -------------------------------- + Written by: Zoltan Herczeg + Email local part: hzmester + Emain domain: freemail.hu + Copyright(c) 2009-2012 Zoltan Herczeg + All rights reserved. + + THE C++ WRAPPER FUNCTIONS + ------------------------- + Contributed by: Google Inc. + Copyright (c) 2007-2012, Google Inc. + All rights reserved. + + THE "BSD" LICENCE + ----------------- + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the name of Google + Inc. nor the names of their contributors may be used to endorse or + promote products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + 6. Some of the cuBLAS library routines were written by or + derived from code written by Vasily Volkov and are subject + to the Modified Berkeley Software Distribution License as + follows: + + Copyright (c) 2007-2009, Regents of the University of California + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of the University of California, Berkeley nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + 7. Some of the cuBLAS library routines were written by or + derived from code written by Davide Barbieri and are + subject to the Modified Berkeley Software Distribution + License as follows: + + Copyright (c) 2008-2009 Davide Barbieri @ University of Rome Tor Vergata. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * The name of the author may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + 8. Some of the cuBLAS library routines were derived from + code developed by the University of Tennessee and are + subject to the Modified Berkeley Software Distribution + License as follows: + + Copyright (c) 2010 The University of Tennessee. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer listed in this license in the documentation and/or + other materials provided with the distribution. + * Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + 9. Some of the cuBLAS library routines were written by or + derived from code written by Jonathan Hogg and are subject + to the Modified Berkeley Software Distribution License as + follows: + + Copyright (c) 2012, The Science and Technology Facilities Council (STFC). + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of the STFC nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE STFC BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + 10. Some of the cuBLAS library routines were written by or + derived from code written by Ahmad M. Abdelfattah, David + Keyes, and Hatem Ltaief, and are subject to the Apache + License, Version 2.0, as follows: + + -- (C) Copyright 2013 King Abdullah University of Science and Technology + Authors: + Ahmad Abdelfattah (ahmad.ahmad@kaust.edu.sa) + David Keyes (david.keyes@kaust.edu.sa) + Hatem Ltaief (hatem.ltaief@kaust.edu.sa) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the King Abdullah University of Science and + Technology nor the names of its contributors may be used to endorse + or promote products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + + 11. Some of the cuSPARSE library routines were written by or + derived from code written by Li-Wen Chang and are subject + to the NCSA Open Source License as follows: + + Copyright (c) 2012, University of Illinois. + + All rights reserved. + + Developed by: IMPACT Group, University of Illinois, http://impact.crhc.illinois.edu + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal with the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimers in the documentation and/or other materials provided + with the distribution. + * Neither the names of IMPACT Group, University of Illinois, nor + the names of its contributors may be used to endorse or promote + products derived from this Software without specific prior + written permission. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE + SOFTWARE. + + 12. Some of the cuRAND library routines were written by or + derived from code written by Mutsuo Saito and Makoto + Matsumoto and are subject to the following license: + + Copyright (c) 2009, 2010 Mutsuo Saito, Makoto Matsumoto and Hiroshima + University. All rights reserved. + + Copyright (c) 2011 Mutsuo Saito, Makoto Matsumoto, Hiroshima + University and University of Tokyo. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of the Hiroshima University nor the names of + its contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + 13. Some of the cuRAND library routines were derived from + code developed by D. E. Shaw Research and are subject to + the following license: + + Copyright 2010-2011, D. E. Shaw Research. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions, and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions, and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of D. E. Shaw Research nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + 14. Some of the Math library routines were written by or + derived from code developed by Norbert Juffa and are + subject to the following license: + + Copyright (c) 2015-2017, Norbert Juffa + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + 15. Licensee's use of the lz4 third party component is + subject to the following terms and conditions: + + Copyright (C) 2011-2013, Yann Collet. + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + 16. The NPP library uses code from the Boost Math Toolkit, + and is subject to the following license: + + Boost Software License - Version 1.0 - August 17th, 2003 + . . . . + + Permission is hereby granted, free of charge, to any person or + organization obtaining a copy of the software and accompanying + documentation covered by this license (the "Software") to use, + reproduce, display, distribute, execute, and transmit the Software, + and to prepare derivative works of the Software, and to permit + third-parties to whom the Software is furnished to do so, all + subject to the following: + + The copyright notices in the Software and this entire statement, + including the above license grant, this restriction and the following + disclaimer, must be included in all copies of the Software, in whole + or in part, and all derivative works of the Software, unless such + copies or derivative works are solely in the form of machine-executable + object code generated by a source language processor. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR + OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + 17. Portions of the Nsight Eclipse Edition is subject to the + following license: + + The Eclipse Foundation makes available all content in this plug-in + ("Content"). Unless otherwise indicated below, the Content is provided + to you under the terms and conditions of the Eclipse Public License + Version 1.0 ("EPL"). A copy of the EPL is available at http:// + www.eclipse.org/legal/epl-v10.html. For purposes of the EPL, "Program" + will mean the Content. + + If you did not receive this Content directly from the Eclipse + Foundation, the Content is being redistributed by another party + ("Redistributor") and different terms and conditions may apply to your + use of any object code in the Content. Check the Redistributor's + license that was provided with the Content. If no such license exists, + contact the Redistributor. Unless otherwise indicated below, the terms + and conditions of the EPL still apply to any source code in the + Content and such source code may be obtained at http://www.eclipse.org. + + 18. Some of the cuBLAS library routines uses code from + OpenAI, which is subject to the following license: + + License URL + https://github.com/openai/openai-gemm/blob/master/LICENSE + + License Text + The MIT License + + Copyright (c) 2016 OpenAI (http://openai.com), 2016 Google Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + + 19. Licensee's use of the Visual Studio Setup Configuration + Samples is subject to the following license: + + The MIT License (MIT) + Copyright (C) Microsoft Corporation. All rights reserved. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + 20. Licensee's use of linmath.h header for CPU functions for + GL vector/matrix operations from lunarG is subject to the + Apache License Version 2.0. + + 21. The DX12-CUDA sample uses the d3dx12.h header, which is + subject to the MIT license . + +----------------- diff --git a/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/METADATA b/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..be77ebbf5aeb12d47b5cb0a0afe85c4ca023b793 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/METADATA @@ -0,0 +1,35 @@ +Metadata-Version: 2.1 +Name: nvidia-nvtx-cu12 +Version: 12.4.127 +Summary: NVIDIA Tools Extension +Home-page: https://developer.nvidia.com/cuda-zone +Author: Nvidia CUDA Installer Team +Author-email: cuda_installer@nvidia.com +License: NVIDIA Proprietary Software +Keywords: cuda,nvidia,runtime,machine learning,deep learning +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: Education +Classifier: Intended Audience :: Science/Research +Classifier: License :: Other/Proprietary License +Classifier: Natural Language :: English +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Topic :: Scientific/Engineering +Classifier: Topic :: Scientific/Engineering :: Mathematics +Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence +Classifier: Topic :: Software Development +Classifier: Topic :: Software Development :: Libraries +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: POSIX :: Linux +Requires-Python: >=3 +License-File: License.txt + +A C-based API for annotating events, code ranges, and resources in your applications. Applications which integrate NVTX can use the Visual Profiler to capture and visualize these events and ranges. diff --git a/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/RECORD b/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..bb07098f6d285dc9f74f0c5ffddf6085664a2dc7 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/RECORD @@ -0,0 +1,36 @@ +nvidia/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +nvidia/__pycache__/__init__.cpython-311.pyc,, +nvidia/nvtx/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +nvidia/nvtx/__pycache__/__init__.cpython-311.pyc,, +nvidia/nvtx/include/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +nvidia/nvtx/include/__pycache__/__init__.cpython-311.pyc,, +nvidia/nvtx/include/nvToolsExt.h,sha256=OiT6v1G2-vlkYnpDQZjiGT1O-THDyk1gw2021qMRvQM,53680 +nvidia/nvtx/include/nvToolsExtCuda.h,sha256=UDA1pbmvoRFmlJ11Et9tIMEztOtOVw-10mO27Q6K8jg,6009 +nvidia/nvtx/include/nvToolsExtCudaRt.h,sha256=6IbgdRGObly53jzRqvsZ4FQoTrXJOJwSyCOLuXr9ncA,5192 +nvidia/nvtx/include/nvToolsExtOpenCL.h,sha256=gETZH9ch_o6MYE_BYQ2pj9SSuxyAo1H4ptmRK-DMWSo,8360 +nvidia/nvtx/include/nvToolsExtSync.h,sha256=wqONIiycUPaUUCzQBmCippilgKt8sOL9tpzG773u0nY,14562 +nvidia/nvtx/include/nvtx3/nvToolsExt.h,sha256=TFEF3fx1043EwMdbS7FqvvavwK0koZeGrIOAsCrB12s,52247 +nvidia/nvtx/include/nvtx3/nvToolsExtCuda.h,sha256=4ZbZHUMcmHRf4SdKB7nH0E3uHd_9ZhZBuwuWPItK-Vs,6204 +nvidia/nvtx/include/nvtx3/nvToolsExtCudaRt.h,sha256=boW0zdYobNFFE9wwxCyzBGBLcSGtdbQ5osKjQGNC2E8,5393 +nvidia/nvtx/include/nvtx3/nvToolsExtOpenCL.h,sha256=RPfsZl3lHAPIOCzTipmz07-vaiIO4cxelcx12EjB2L0,8563 +nvidia/nvtx/include/nvtx3/nvToolsExtSync.h,sha256=C-HIVBaupxYom3BqMggQ_ePq1bxFhw8kXsOfYJKBWrI,14756 +nvidia/nvtx/include/nvtx3/nvtxDetail/nvtxImpl.h,sha256=jEnYF3MyLsD72euw2It3Bz0X0GK4Xv_htEd8BeIrPjY,23333 +nvidia/nvtx/include/nvtx3/nvtxDetail/nvtxImplCore.h,sha256=sYpWqZfYrjsMddxtezPX3qSTIbAOn4dlEoLiYQ9M2nM,9756 +nvidia/nvtx/include/nvtx3/nvtxDetail/nvtxImplCudaRt_v3.h,sha256=SoaiprvsI80yLmEAnlFX0iFufv6RtKjjMMrVwQZjjQI,4775 +nvidia/nvtx/include/nvtx3/nvtxDetail/nvtxImplCuda_v3.h,sha256=IEor-ISqComCRGVDdIzKBLU3eWCuDI0Igqz-eRKKcvg,5550 +nvidia/nvtx/include/nvtx3/nvtxDetail/nvtxImplOpenCL_v3.h,sha256=iPR2x74bJE3plFQBT9FWGBaTm4sC-Pll6WAjpKRnz7g,8275 +nvidia/nvtx/include/nvtx3/nvtxDetail/nvtxImplSync_v3.h,sha256=TqwQfEUVbwc58bpHioE13NMweFhOuHXNql65BnLzhvc,5022 +nvidia/nvtx/include/nvtx3/nvtxDetail/nvtxInit.h,sha256=foajOFacvLGx3BN5ntw5v8o4J3OY4hqkVZE5ZC0x3e4,14716 +nvidia/nvtx/include/nvtx3/nvtxDetail/nvtxInitDecls.h,sha256=-Qyxcy9CDXOBhEtYZ8L7iYd6daJ9aCeyQM48X0BafMM,9361 +nvidia/nvtx/include/nvtx3/nvtxDetail/nvtxInitDefs.h,sha256=dLhOV4knhNrmT2DnUNzXreOt_Qc6GAa3yIlmqJFCeVI,35432 +nvidia/nvtx/include/nvtx3/nvtxDetail/nvtxLinkOnce.h,sha256=Jp-z6LTz_p8fKRulcFfdcskIxzcZ6ybbHkGB9mpJa2M,3863 +nvidia/nvtx/include/nvtx3/nvtxDetail/nvtxTypes.h,sha256=jkbCwyvIP1G-Ef8SwYp4kDi69hjZbzaxKSk7ScgrNI8,17352 +nvidia/nvtx/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +nvidia/nvtx/lib/__pycache__/__init__.cpython-311.pyc,, +nvidia/nvtx/lib/libnvToolsExt.so.1,sha256=hH148nXIzJdEKieAcyBL3BoACf_CVZv3JIxw2SEF39w,40136 +nvidia_nvtx_cu12-12.4.127.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +nvidia_nvtx_cu12-12.4.127.dist-info/License.txt,sha256=rW9YU_ugyg0VnQ9Y1JrkmDDC-Mk_epJki5zpCttMbM0,59262 +nvidia_nvtx_cu12-12.4.127.dist-info/METADATA,sha256=9RLXm3hRj_WuKLEP5eYxTAhsLGAeFt3LoHymjVqrI7I,1660 +nvidia_nvtx_cu12-12.4.127.dist-info/RECORD,, +nvidia_nvtx_cu12-12.4.127.dist-info/WHEEL,sha256=XDTs3wIbcE-BcRO08VJlZpA6z9OaC1mOKPCGGGwuM2g,109 +nvidia_nvtx_cu12-12.4.127.dist-info/top_level.txt,sha256=fTkAtiFuL16nUrB9ytDDtpytz2t0B4NvYTnRzwAhO14,7 diff --git a/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/WHEEL b/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..e6c30e957cfb045017a9fef3430bb8ee87c4a074 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.42.0) +Root-Is-Purelib: true +Tag: py3-none-manylinux2014_x86_64 + diff --git a/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/top_level.txt b/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..862f7abf232cdfbb928609856247292e81c9decb --- /dev/null +++ b/.venv/lib/python3.11/site-packages/nvidia_nvtx_cu12-12.4.127.dist-info/top_level.txt @@ -0,0 +1 @@ +nvidia diff --git a/.venv/lib/python3.11/site-packages/pyparsing-3.2.1.dist-info/INSTALLER b/.venv/lib/python3.11/site-packages/pyparsing-3.2.1.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/pyparsing-3.2.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.11/site-packages/pyparsing-3.2.1.dist-info/LICENSE b/.venv/lib/python3.11/site-packages/pyparsing-3.2.1.dist-info/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..1bf98523e33170372cf0702f03e38dadec3c5094 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/pyparsing-3.2.1.dist-info/LICENSE @@ -0,0 +1,18 @@ +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/.venv/lib/python3.11/site-packages/pyparsing-3.2.1.dist-info/METADATA b/.venv/lib/python3.11/site-packages/pyparsing-3.2.1.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..6b5fbefef6063480e7bec0f68160719fad702dc1 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/pyparsing-3.2.1.dist-info/METADATA @@ -0,0 +1,124 @@ +Metadata-Version: 2.1 +Name: pyparsing +Version: 3.2.1 +Summary: pyparsing module - Classes and methods to define and execute parsing grammars +Author-email: Paul McGuire +Requires-Python: >=3.9 +Description-Content-Type: text/x-rst +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: Information Technology +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Software Development :: Compilers +Classifier: Topic :: Text Processing +Classifier: Typing :: Typed +Requires-Dist: railroad-diagrams ; extra == "diagrams" +Requires-Dist: jinja2 ; extra == "diagrams" +Project-URL: Homepage, https://github.com/pyparsing/pyparsing/ +Provides-Extra: diagrams + +PyParsing -- A Python Parsing Module +==================================== + +|Version| |Build Status| |Coverage| |License| |Python Versions| |Snyk Score| + +Introduction +============ + +The pyparsing module is an alternative approach to creating and +executing simple grammars, vs. the traditional lex/yacc approach, or the +use of regular expressions. The pyparsing module provides a library of +classes that client code uses to construct the grammar directly in +Python code. + +*[Since first writing this description of pyparsing in late 2003, this +technique for developing parsers has become more widespread, under the +name Parsing Expression Grammars - PEGs. See more information on PEGs* +`here `__ +*.]* + +Here is a program to parse ``"Hello, World!"`` (or any greeting of the form +``"salutation, addressee!"``): + +.. code:: python + + from pyparsing import Word, alphas + greet = Word(alphas) + "," + Word(alphas) + "!" + hello = "Hello, World!" + print(hello, "->", greet.parseString(hello)) + +The program outputs the following:: + + Hello, World! -> ['Hello', ',', 'World', '!'] + +The Python representation of the grammar is quite readable, owing to the +self-explanatory class names, and the use of '+', '|' and '^' operator +definitions. + +The parsed results returned from ``parseString()`` is a collection of type +``ParseResults``, which can be accessed as a +nested list, a dictionary, or an object with named attributes. + +The pyparsing module handles some of the problems that are typically +vexing when writing text parsers: + +- extra or missing whitespace (the above program will also handle ``"Hello,World!"``, ``"Hello , World !"``, etc.) +- quoted strings +- embedded comments + +The examples directory includes a simple SQL parser, simple CORBA IDL +parser, a config file parser, a chemical formula parser, and a four- +function algebraic notation parser, among many others. + +Documentation +============= + +There are many examples in the online docstrings of the classes +and methods in pyparsing. You can find them compiled into `online docs `__. Additional +documentation resources and project info are listed in the online +`GitHub wiki `__. An +entire directory of examples can be found `here `__. + +License +======= + +MIT License. See header of the `pyparsing __init__.py `__ file. + +History +======= + +See `CHANGES `__ file. + +.. |Build Status| image:: https://github.com/pyparsing/pyparsing/actions/workflows/ci.yml/badge.svg + :target: https://github.com/pyparsing/pyparsing/actions/workflows/ci.yml + +.. |Coverage| image:: https://codecov.io/gh/pyparsing/pyparsing/branch/master/graph/badge.svg + :target: https://codecov.io/gh/pyparsing/pyparsing + +.. |Version| image:: https://img.shields.io/pypi/v/pyparsing?style=flat-square + :target: https://pypi.org/project/pyparsing/ + :alt: Version + +.. |License| image:: https://img.shields.io/pypi/l/pyparsing.svg?style=flat-square + :target: https://pypi.org/project/pyparsing/ + :alt: License + +.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/pyparsing.svg?style=flat-square + :target: https://pypi.org/project/python-liquid/ + :alt: Python versions + +.. |Snyk Score| image:: https://snyk.io//advisor/python/pyparsing/badge.svg + :target: https://snyk.io//advisor/python/pyparsing + :alt: pyparsing + diff --git a/.venv/lib/python3.11/site-packages/pyparsing-3.2.1.dist-info/RECORD b/.venv/lib/python3.11/site-packages/pyparsing-3.2.1.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..f2e1629350390ac66544fdda5f007dd10663dc9f --- /dev/null +++ b/.venv/lib/python3.11/site-packages/pyparsing-3.2.1.dist-info/RECORD @@ -0,0 +1,28 @@ +pyparsing-3.2.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pyparsing-3.2.1.dist-info/LICENSE,sha256=ENUSChaAWAT_2otojCIL-06POXQbVzIGBNRVowngGXI,1023 +pyparsing-3.2.1.dist-info/METADATA,sha256=Cn5py_teLACvRMsW9ZrQgb7HGiy3ohpVn0xlg0YNG0k,4989 +pyparsing-3.2.1.dist-info/RECORD,, +pyparsing-3.2.1.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +pyparsing/__init__.py,sha256=F1Bz3e2TP95q_i5nBz4_3HOgrp_UpxyAYnLtvs6MhIU,9038 +pyparsing/__pycache__/__init__.cpython-311.pyc,, +pyparsing/__pycache__/actions.cpython-311.pyc,, +pyparsing/__pycache__/common.cpython-311.pyc,, +pyparsing/__pycache__/core.cpython-311.pyc,, +pyparsing/__pycache__/exceptions.cpython-311.pyc,, +pyparsing/__pycache__/helpers.cpython-311.pyc,, +pyparsing/__pycache__/results.cpython-311.pyc,, +pyparsing/__pycache__/testing.cpython-311.pyc,, +pyparsing/__pycache__/unicode.cpython-311.pyc,, +pyparsing/__pycache__/util.cpython-311.pyc,, +pyparsing/actions.py,sha256=ULt36RofyW2bDxa-z-5NpHDk46zcT5V5ibaYcqUTm30,7257 +pyparsing/common.py,sha256=SyZAEQpwDAPOpUenOltIv-y1N-tzSN3nCEzNYcOpiDw,13673 +pyparsing/core.py,sha256=N43lH6j1FJ7JBrKXAXapwGYjxPc7PqPi6inyv8CQN-I,231982 +pyparsing/diagram/__init__.py,sha256=bEsqh-GrtLHQFnqtBoXGLZqrB8uqM38dUhgKdNByJwU,26563 +pyparsing/diagram/__pycache__/__init__.cpython-311.pyc,, +pyparsing/exceptions.py,sha256=30rC4NZxcp0dHh5KiwbWkwRFG7viRlY0DsgzAupZFRE,9886 +pyparsing/helpers.py,sha256=Xi6INfOY0lnqOk66vK_2KQQ_v913QzVNLg6yNuLGq-M,39527 +pyparsing/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pyparsing/results.py,sha256=dyIT3HPwR1n_7klZ1Lbf3dQId5JiCn6ksM1Ktn9JGUo,26246 +pyparsing/testing.py,sha256=r-kKXcv_8r1G-4vrprBkJeuQFpr94OSm0jlXdGwAYF0,14682 +pyparsing/unicode.py,sha256=doanv7BYQB4EdQRfdXigaiV_SDhZyyaBSwgvVEz6eXc,10614 +pyparsing/util.py,sha256=M9wzp560rlBaCuRv7smMvcLBIxMJstBNKweHIE91onU,12975 diff --git a/.venv/lib/python3.11/site-packages/pyparsing-3.2.1.dist-info/WHEEL b/.venv/lib/python3.11/site-packages/pyparsing-3.2.1.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..3b5e64b5e6c4a210201d1676a891fd57b15cda99 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/pyparsing-3.2.1.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.9.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/lib/python3.11/site-packages/pytest/__init__.py b/.venv/lib/python3.11/site-packages/pytest/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..90abcdab036d3a3a5153922401d0cbb9ffe458e3 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/pytest/__init__.py @@ -0,0 +1,172 @@ +# PYTHON_ARGCOMPLETE_OK +"""pytest: unit and functional testing with Python.""" + +from __future__ import annotations + +from _pytest import __version__ +from _pytest import version_tuple +from _pytest._code import ExceptionInfo +from _pytest.assertion import register_assert_rewrite +from _pytest.cacheprovider import Cache +from _pytest.capture import CaptureFixture +from _pytest.config import cmdline +from _pytest.config import Config +from _pytest.config import console_main +from _pytest.config import ExitCode +from _pytest.config import hookimpl +from _pytest.config import hookspec +from _pytest.config import main +from _pytest.config import PytestPluginManager +from _pytest.config import UsageError +from _pytest.config.argparsing import OptionGroup +from _pytest.config.argparsing import Parser +from _pytest.debugging import pytestPDB as __pytestPDB +from _pytest.doctest import DoctestItem +from _pytest.fixtures import fixture +from _pytest.fixtures import FixtureDef +from _pytest.fixtures import FixtureLookupError +from _pytest.fixtures import FixtureRequest +from _pytest.fixtures import yield_fixture +from _pytest.freeze_support import freeze_includes +from _pytest.legacypath import TempdirFactory +from _pytest.legacypath import Testdir +from _pytest.logging import LogCaptureFixture +from _pytest.main import Dir +from _pytest.main import Session +from _pytest.mark import Mark +from _pytest.mark import MARK_GEN as mark +from _pytest.mark import MarkDecorator +from _pytest.mark import MarkGenerator +from _pytest.mark import param +from _pytest.monkeypatch import MonkeyPatch +from _pytest.nodes import Collector +from _pytest.nodes import Directory +from _pytest.nodes import File +from _pytest.nodes import Item +from _pytest.outcomes import exit +from _pytest.outcomes import fail +from _pytest.outcomes import importorskip +from _pytest.outcomes import skip +from _pytest.outcomes import xfail +from _pytest.pytester import HookRecorder +from _pytest.pytester import LineMatcher +from _pytest.pytester import Pytester +from _pytest.pytester import RecordedHookCall +from _pytest.pytester import RunResult +from _pytest.python import Class +from _pytest.python import Function +from _pytest.python import Metafunc +from _pytest.python import Module +from _pytest.python import Package +from _pytest.python_api import approx +from _pytest.python_api import raises +from _pytest.recwarn import deprecated_call +from _pytest.recwarn import WarningsRecorder +from _pytest.recwarn import warns +from _pytest.reports import CollectReport +from _pytest.reports import TestReport +from _pytest.runner import CallInfo +from _pytest.stash import Stash +from _pytest.stash import StashKey +from _pytest.terminal import TestShortLogReport +from _pytest.tmpdir import TempPathFactory +from _pytest.warning_types import PytestAssertRewriteWarning +from _pytest.warning_types import PytestCacheWarning +from _pytest.warning_types import PytestCollectionWarning +from _pytest.warning_types import PytestConfigWarning +from _pytest.warning_types import PytestDeprecationWarning +from _pytest.warning_types import PytestExperimentalApiWarning +from _pytest.warning_types import PytestRemovedIn9Warning +from _pytest.warning_types import PytestReturnNotNoneWarning +from _pytest.warning_types import PytestUnhandledCoroutineWarning +from _pytest.warning_types import PytestUnhandledThreadExceptionWarning +from _pytest.warning_types import PytestUnknownMarkWarning +from _pytest.warning_types import PytestUnraisableExceptionWarning +from _pytest.warning_types import PytestWarning + + +set_trace = __pytestPDB.set_trace + + +__all__ = [ + "__version__", + "approx", + "Cache", + "CallInfo", + "CaptureFixture", + "Class", + "cmdline", + "Collector", + "CollectReport", + "Config", + "console_main", + "deprecated_call", + "Dir", + "Directory", + "DoctestItem", + "exit", + "ExceptionInfo", + "ExitCode", + "fail", + "File", + "fixture", + "FixtureDef", + "FixtureLookupError", + "FixtureRequest", + "freeze_includes", + "Function", + "hookimpl", + "HookRecorder", + "hookspec", + "importorskip", + "Item", + "LineMatcher", + "LogCaptureFixture", + "main", + "mark", + "Mark", + "MarkDecorator", + "MarkGenerator", + "Metafunc", + "Module", + "MonkeyPatch", + "OptionGroup", + "Package", + "param", + "Parser", + "PytestAssertRewriteWarning", + "PytestCacheWarning", + "PytestCollectionWarning", + "PytestConfigWarning", + "PytestDeprecationWarning", + "PytestExperimentalApiWarning", + "PytestRemovedIn9Warning", + "PytestReturnNotNoneWarning", + "Pytester", + "PytestPluginManager", + "PytestUnhandledCoroutineWarning", + "PytestUnhandledThreadExceptionWarning", + "PytestUnknownMarkWarning", + "PytestUnraisableExceptionWarning", + "PytestWarning", + "raises", + "RecordedHookCall", + "register_assert_rewrite", + "RunResult", + "Session", + "set_trace", + "skip", + "Stash", + "StashKey", + "version_tuple", + "TempdirFactory", + "TempPathFactory", + "Testdir", + "TestReport", + "TestShortLogReport", + "UsageError", + "WarningsRecorder", + "warns", + "xfail", + "yield_fixture", +] diff --git a/.venv/lib/python3.11/site-packages/pytest/__main__.py b/.venv/lib/python3.11/site-packages/pytest/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..cccab5d57b86352e51cb59df8b023c42a9304d65 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/pytest/__main__.py @@ -0,0 +1,9 @@ +"""The pytest entry point.""" + +from __future__ import annotations + +import pytest + + +if __name__ == "__main__": + raise SystemExit(pytest.console_main()) diff --git a/.venv/lib/python3.11/site-packages/pytest/__pycache__/__init__.cpython-311.pyc b/.venv/lib/python3.11/site-packages/pytest/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0bc69fbc78747d961755b0dc10db57a75b318884 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/pytest/__pycache__/__init__.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/pytest/__pycache__/__main__.cpython-311.pyc b/.venv/lib/python3.11/site-packages/pytest/__pycache__/__main__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..49a254e3cf786b6aa587444e84e6eb780074fe1e Binary files /dev/null and b/.venv/lib/python3.11/site-packages/pytest/__pycache__/__main__.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/pytest/py.typed b/.venv/lib/python3.11/site-packages/pytest/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/lib/python3.11/site-packages/torchaudio/_extension/__init__.py b/.venv/lib/python3.11/site-packages/torchaudio/_extension/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5c2ff55583ba48aa5859e26bfceaba9a78ee23e2 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/torchaudio/_extension/__init__.py @@ -0,0 +1,74 @@ +import logging +import os +import sys + +from torchaudio._internal.module_utils import fail_with_message, is_module_available, no_op + +from .utils import _check_cuda_version, _init_dll_path, _init_sox, _LazyImporter, _load_lib + +_LG = logging.getLogger(__name__) + + +# Note: +# `_check_cuda_version` is not meant to be used by regular users. +# Builder uses it for debugging purpose, so we export it. +# https://github.com/pytorch/builder/blob/e2e4542b8eb0bdf491214451a1a4128bd606cce2/test/smoke_test/smoke_test.py#L80 +__all__ = [ + "_check_cuda_version", + "_IS_TORCHAUDIO_EXT_AVAILABLE", + "_IS_RIR_AVAILABLE", + "lazy_import_sox_ext", +] + + +if os.name == "nt" and (3, 8) <= sys.version_info < (3, 9): + _init_dll_path() + + +# When the extension module is built, we initialize it. +# In case of an error, we do not catch the failure as it suggests there is something +# wrong with the installation. +_IS_TORCHAUDIO_EXT_AVAILABLE = is_module_available("torchaudio.lib._torchaudio") +# RIR features are implemented in _torchaudio extension, but they can be individually +# turned on/off at build time. Available means that _torchaudio is loaded properly, and +# RIR features are found there. +_IS_RIR_AVAILABLE = False +_IS_ALIGN_AVAILABLE = False +if _IS_TORCHAUDIO_EXT_AVAILABLE: + _load_lib("libtorchaudio") + + import torchaudio.lib._torchaudio # noqa + + _check_cuda_version() + _IS_RIR_AVAILABLE = torchaudio.lib._torchaudio.is_rir_available() + _IS_ALIGN_AVAILABLE = torchaudio.lib._torchaudio.is_align_available() + + +_SOX_EXT = None + + +def lazy_import_sox_ext(): + """Load SoX integration based on availability in lazy manner""" + + global _SOX_EXT + if _SOX_EXT is None: + _SOX_EXT = _LazyImporter("_torchaudio_sox", _init_sox) + return _SOX_EXT + + +fail_if_no_rir = ( + no_op + if _IS_RIR_AVAILABLE + else fail_with_message( + "requires RIR extension, but TorchAudio is not compiled with it. Please build TorchAudio with RIR support." + ) +) + +fail_if_no_align = ( + no_op + if _IS_ALIGN_AVAILABLE + else fail_with_message( + "Requires alignment extension, but TorchAudio is not compiled with it. \ + Please build TorchAudio with alignment support." + ) +) diff --git a/.venv/lib/python3.11/site-packages/torchaudio/_extension/__pycache__/__init__.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/_extension/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae922d172f71ea26a82461f874569766ad15686a Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/_extension/__pycache__/__init__.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/_extension/__pycache__/utils.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/_extension/__pycache__/utils.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2bc093c22bcef5921403ae243579e31211cde086 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/_extension/__pycache__/utils.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/_extension/utils.py b/.venv/lib/python3.11/site-packages/torchaudio/_extension/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..c5660a1e22c2b7f73ee6f351fb8b37cde4c3260f --- /dev/null +++ b/.venv/lib/python3.11/site-packages/torchaudio/_extension/utils.py @@ -0,0 +1,180 @@ +"""Module to implement logics used for initializing extensions. + +The implementations here should be stateless. +They should not depend on external state. +Anything that depends on external state should happen in __init__.py +""" +import importlib +import logging +import os +import types +from pathlib import Path + +import torch +from torchaudio._internal.module_utils import eval_env + +_LG = logging.getLogger(__name__) +_LIB_DIR = Path(__file__).parent.parent / "lib" + + +def _get_lib_path(lib: str): + suffix = "pyd" if os.name == "nt" else "so" + path = _LIB_DIR / f"{lib}.{suffix}" + return path + + +def _load_lib(lib: str) -> bool: + """Load extension module + + Note: + In case `torchaudio` is deployed with `pex` format, the library file + is not in a standard location. + In this case, we expect that `libtorchaudio` is available somewhere + in the search path of dynamic loading mechanism, so that importing + `_torchaudio` will have library loader find and load `libtorchaudio`. + This is the reason why the function should not raising an error when the library + file is not found. + + Returns: + bool: + True if the library file is found AND the library loaded without failure. + False if the library file is not found (like in the case where torchaudio + is deployed with pex format, thus the shared library file is + in a non-standard location.). + If the library file is found but there is an issue loading the library, + (such as missing dependency) then this function raises the exception as-is. + + Raises: + Exception: + If the library file is found, but there is an issue loading the library file, + (when underlying `ctype.DLL` throws an exception), this function will pass + the exception as-is, instead of catching it and returning bool. + The expected case is `OSError` thrown by `ctype.DLL` when a dynamic dependency + is not found. + This behavior was chosen because the expected failure case is not recoverable. + If a dependency is missing, then users have to install it. + """ + path = _get_lib_path(lib) + if not path.exists(): + return False + torch.ops.load_library(path) + return True + + +def _import_sox_ext(): + if os.name == "nt": + raise RuntimeError("sox extension is not supported on Windows") + if not eval_env("TORCHAUDIO_USE_SOX", True): + raise RuntimeError("sox extension is disabled. (TORCHAUDIO_USE_SOX=0)") + + ext = "torchaudio.lib._torchaudio_sox" + + if not importlib.util.find_spec(ext): + raise RuntimeError( + # fmt: off + "TorchAudio is not built with sox extension. " + "Please build TorchAudio with libsox support. (BUILD_SOX=1)" + # fmt: on + ) + + _load_lib("libtorchaudio_sox") + return importlib.import_module(ext) + + +def _init_sox(): + ext = _import_sox_ext() + ext.set_verbosity(0) + + import atexit + + torch.ops.torchaudio_sox.initialize_sox_effects() + atexit.register(torch.ops.torchaudio_sox.shutdown_sox_effects) + + # Bundle functions registered with TORCH_LIBRARY into extension + # so that they can also be accessed in the same (lazy) manner + # from the extension. + keys = [ + "get_info", + "load_audio_file", + "save_audio_file", + "apply_effects_tensor", + "apply_effects_file", + ] + for key in keys: + setattr(ext, key, getattr(torch.ops.torchaudio_sox, key)) + + return ext + + +class _LazyImporter(types.ModuleType): + """Lazily import module/extension.""" + + def __init__(self, name, import_func): + super().__init__(name) + self.import_func = import_func + self.module = None + + # Note: + # Python caches what was retrieved with `__getattr__`, so this method will not be + # called again for the same item. + def __getattr__(self, item): + self._import_once() + return getattr(self.module, item) + + def __repr__(self): + if self.module is None: + return f"" + return repr(self.module) + + def __dir__(self): + self._import_once() + return dir(self.module) + + def _import_once(self): + if self.module is None: + self.module = self.import_func() + # Note: + # By attaching the module attributes to self, + # module attributes are directly accessible. + # This allows to avoid calling __getattr__ for every attribute access. + self.__dict__.update(self.module.__dict__) + + def is_available(self): + try: + self._import_once() + except Exception: + return False + return True + + +def _init_dll_path(): + # On Windows Python-3.8+ has `os.add_dll_directory` call, + # which is called to configure dll search path. + # To find cuda related dlls we need to make sure the + # conda environment/bin path is configured Please take a look: + # https://stackoverflow.com/questions/59330863/cant-import-dll-module-in-python + # Please note: if some path can't be added using add_dll_directory we simply ignore this path + for path in os.environ.get("PATH", "").split(";"): + if os.path.exists(path): + try: + os.add_dll_directory(path) + except Exception: + pass + + +def _check_cuda_version(): + import torchaudio.lib._torchaudio + + version = torchaudio.lib._torchaudio.cuda_version() + if version is not None and torch.version.cuda is not None: + version_str = str(version) + ta_version = f"{version_str[:-3]}.{version_str[-2]}" + t_version = torch.version.cuda.split(".") + t_version = f"{t_version[0]}.{t_version[1]}" + if ta_version != t_version: + raise RuntimeError( + "Detected that PyTorch and TorchAudio were compiled with different CUDA versions. " + f"PyTorch has CUDA version {t_version} whereas TorchAudio has CUDA version {ta_version}. " + "Please install the TorchAudio version that matches your PyTorch version." + ) + return version diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/__init__.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3798f171f31c13e4b835ea575e763b7f0dbd8a27 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/__init__.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/cmuarctic.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/cmuarctic.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f2e6c9536c99fb06cc0741e87546d737bf0e1617 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/cmuarctic.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/cmudict.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/cmudict.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3b0b67693ba62723e5c495fb0522a00061d977ac Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/cmudict.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/commonvoice.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/commonvoice.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4c41945889846e9598d7e0471f813c7583454068 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/commonvoice.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/dr_vctk.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/dr_vctk.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d0cab97b5a13b3171f9d5ccb91a57177956d938f Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/dr_vctk.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/fluentcommands.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/fluentcommands.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..91d607c8651b206cc551cda8b1b5eb34d817082d Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/fluentcommands.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/gtzan.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/gtzan.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ccce7e21ddf64e5774d399f5eee2f49e6a841c28 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/gtzan.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/iemocap.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/iemocap.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b6ebf7e223f302a19833c0081904fe1496cfee06 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/iemocap.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/librispeech.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/librispeech.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5f2cedac78136cc7f39006f71bcd28dfea7eee67 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/librispeech.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/ljspeech.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/ljspeech.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92f2bdf4a586824ab130fa9094c614f667d4f24e Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/ljspeech.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/musdb_hq.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/musdb_hq.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e2c39dc9e74bd3d58dec682e78e3ae3d72346dd Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/musdb_hq.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/quesst14.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/quesst14.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a09acec909aa5a71a5134fa8abb7b0960571e2af Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/quesst14.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/snips.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/snips.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f985791c02e643c671f15266eb21b08318f9a6dd Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/snips.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/speechcommands.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/speechcommands.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e6de89c3002c7ae28cb1b8bf7fcb77ef305f5e70 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/speechcommands.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/tedlium.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/tedlium.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f9da8683ae1f6088eb3450b493692dd0cd68683e Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/tedlium.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/utils.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/utils.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b5bc94cdc90c94276baa13527bebb98ec6665a3e Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/utils.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/vctk.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/vctk.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8d820ed4300cd86040226bafd7aeb6902f40964b Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/vctk.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/voxceleb1.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/voxceleb1.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fa9a1da1bff5a923b359456e70a581da1bfbdd34 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/voxceleb1.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/yesno.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/yesno.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..832f7bf16e61fa9c193a5088aed8c9eeec832900 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/datasets/__pycache__/yesno.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/sox_effects/__init__.py b/.venv/lib/python3.11/site-packages/torchaudio/sox_effects/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..93c63cae1ded8a37226a76eec89796eb4902eafc --- /dev/null +++ b/.venv/lib/python3.11/site-packages/torchaudio/sox_effects/__init__.py @@ -0,0 +1,10 @@ +from .sox_effects import apply_effects_file, apply_effects_tensor, effect_names, init_sox_effects, shutdown_sox_effects + + +__all__ = [ + "init_sox_effects", + "shutdown_sox_effects", + "effect_names", + "apply_effects_tensor", + "apply_effects_file", +] diff --git a/.venv/lib/python3.11/site-packages/torchaudio/sox_effects/__pycache__/__init__.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/sox_effects/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5a174aa5a4c8985e6820c4ea298dcc9954ca0ae8 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/sox_effects/__pycache__/__init__.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/sox_effects/__pycache__/sox_effects.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/sox_effects/__pycache__/sox_effects.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3662465306ddb29d15f711094d00ce09aef696a4 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/sox_effects/__pycache__/sox_effects.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/sox_effects/sox_effects.py b/.venv/lib/python3.11/site-packages/torchaudio/sox_effects/sox_effects.py new file mode 100644 index 0000000000000000000000000000000000000000..3d64d465acada0911e86af2f74d2b58dba9352ad --- /dev/null +++ b/.venv/lib/python3.11/site-packages/torchaudio/sox_effects/sox_effects.py @@ -0,0 +1,272 @@ +import os +from typing import List, Optional, Tuple + +import torch +import torchaudio +from torchaudio._internal.module_utils import deprecated +from torchaudio.utils.sox_utils import list_effects + + +sox_ext = torchaudio._extension.lazy_import_sox_ext() + + +@deprecated("Please remove the call. This function is called automatically.") +def init_sox_effects(): + """Initialize resources required to use sox effects. + + Note: + You do not need to call this function manually. It is called automatically. + + Once initialized, you do not need to call this function again across the multiple uses of + sox effects though it is safe to do so as long as :func:`shutdown_sox_effects` is not called yet. + Once :func:`shutdown_sox_effects` is called, you can no longer use SoX effects and initializing + again will result in error. + """ + pass + + +@deprecated("Please remove the call. This function is called automatically.") +def shutdown_sox_effects(): + """Clean up resources required to use sox effects. + + Note: + You do not need to call this function manually. It is called automatically. + + It is safe to call this function multiple times. + Once :py:func:`shutdown_sox_effects` is called, you can no longer use SoX effects and + initializing again will result in error. + """ + pass + + +def effect_names() -> List[str]: + """Gets list of valid sox effect names + + Returns: + List[str]: list of available effect names. + + Example + >>> torchaudio.sox_effects.effect_names() + ['allpass', 'band', 'bandpass', ... ] + """ + return list(list_effects().keys()) + + +def apply_effects_tensor( + tensor: torch.Tensor, + sample_rate: int, + effects: List[List[str]], + channels_first: bool = True, +) -> Tuple[torch.Tensor, int]: + """Apply sox effects to given Tensor + + .. devices:: CPU + + .. properties:: TorchScript + + Note: + This function only works on CPU Tensors. + This function works in the way very similar to ``sox`` command, however there are slight + differences. For example, ``sox`` command adds certain effects automatically (such as + ``rate`` effect after ``speed`` and ``pitch`` and other effects), but this function does + only applies the given effects. (Therefore, to actually apply ``speed`` effect, you also + need to give ``rate`` effect with desired sampling rate.). + + Args: + tensor (torch.Tensor): Input 2D CPU Tensor. + sample_rate (int): Sample rate + effects (List[List[str]]): List of effects. + channels_first (bool, optional): Indicates if the input Tensor's dimension is + `[channels, time]` or `[time, channels]` + + Returns: + (Tensor, int): Resulting Tensor and sample rate. + The resulting Tensor has the same ``dtype`` as the input Tensor, and + the same channels order. The shape of the Tensor can be different based on the + effects applied. Sample rate can also be different based on the effects applied. + + Example - Basic usage + >>> + >>> # Defines the effects to apply + >>> effects = [ + ... ['gain', '-n'], # normalises to 0dB + ... ['pitch', '5'], # 5 cent pitch shift + ... ['rate', '8000'], # resample to 8000 Hz + ... ] + >>> + >>> # Generate pseudo wave: + >>> # normalized, channels first, 2ch, sampling rate 16000, 1 second + >>> sample_rate = 16000 + >>> waveform = 2 * torch.rand([2, sample_rate * 1]) - 1 + >>> waveform.shape + torch.Size([2, 16000]) + >>> waveform + tensor([[ 0.3138, 0.7620, -0.9019, ..., -0.7495, -0.4935, 0.5442], + [-0.0832, 0.0061, 0.8233, ..., -0.5176, -0.9140, -0.2434]]) + >>> + >>> # Apply effects + >>> waveform, sample_rate = apply_effects_tensor( + ... wave_form, sample_rate, effects, channels_first=True) + >>> + >>> # Check the result + >>> # The new waveform is sampling rate 8000, 1 second. + >>> # normalization and channel order are preserved + >>> waveform.shape + torch.Size([2, 8000]) + >>> waveform + tensor([[ 0.5054, -0.5518, -0.4800, ..., -0.0076, 0.0096, -0.0110], + [ 0.1331, 0.0436, -0.3783, ..., -0.0035, 0.0012, 0.0008]]) + >>> sample_rate + 8000 + + Example - Torchscript-able transform + >>> + >>> # Use `apply_effects_tensor` in `torch.nn.Module` and dump it to file, + >>> # then run sox effect via Torchscript runtime. + >>> + >>> class SoxEffectTransform(torch.nn.Module): + ... effects: List[List[str]] + ... + ... def __init__(self, effects: List[List[str]]): + ... super().__init__() + ... self.effects = effects + ... + ... def forward(self, tensor: torch.Tensor, sample_rate: int): + ... return sox_effects.apply_effects_tensor( + ... tensor, sample_rate, self.effects) + ... + ... + >>> # Create transform object + >>> effects = [ + ... ["lowpass", "-1", "300"], # apply single-pole lowpass filter + ... ["rate", "8000"], # change sample rate to 8000 + ... ] + >>> transform = SoxEffectTensorTransform(effects, input_sample_rate) + >>> + >>> # Dump it to file and load + >>> path = 'sox_effect.zip' + >>> torch.jit.script(trans).save(path) + >>> transform = torch.jit.load(path) + >>> + >>>> # Run transform + >>> waveform, input_sample_rate = torchaudio.load("input.wav") + >>> waveform, sample_rate = transform(waveform, input_sample_rate) + >>> assert sample_rate == 8000 + """ + return sox_ext.apply_effects_tensor(tensor, sample_rate, effects, channels_first) + + +def apply_effects_file( + path: str, + effects: List[List[str]], + normalize: bool = True, + channels_first: bool = True, + format: Optional[str] = None, +) -> Tuple[torch.Tensor, int]: + """Apply sox effects to the audio file and load the resulting data as Tensor + + .. devices:: CPU + + .. properties:: TorchScript + + Note: + This function works in the way very similar to ``sox`` command, however there are slight + differences. For example, ``sox`` commnad adds certain effects automatically (such as + ``rate`` effect after ``speed``, ``pitch`` etc), but this function only applies the given + effects. Therefore, to actually apply ``speed`` effect, you also need to give ``rate`` + effect with desired sampling rate, because internally, ``speed`` effects only alter sampling + rate and leave samples untouched. + + Args: + path (path-like object): + Source of audio data. + effects (List[List[str]]): List of effects. + normalize (bool, optional): + When ``True``, this function converts the native sample type to ``float32``. + Default: ``True``. + + If input file is integer WAV, giving ``False`` will change the resulting Tensor type to + integer type. + This argument has no effect for formats other than integer WAV type. + + channels_first (bool, optional): When True, the returned Tensor has dimension `[channel, time]`. + Otherwise, the returned Tensor's dimension is `[time, channel]`. + format (str or None, optional): + Override the format detection with the given format. + Providing the argument might help when libsox can not infer the format + from header or extension, + + Returns: + (Tensor, int): Resulting Tensor and sample rate. + If ``normalize=True``, the resulting Tensor is always ``float32`` type. + If ``normalize=False`` and the input audio file is of integer WAV file, then the + resulting Tensor has corresponding integer type. (Note 24 bit integer type is not supported) + If ``channels_first=True``, the resulting Tensor has dimension `[channel, time]`, + otherwise `[time, channel]`. + + Example - Basic usage + >>> + >>> # Defines the effects to apply + >>> effects = [ + ... ['gain', '-n'], # normalises to 0dB + ... ['pitch', '5'], # 5 cent pitch shift + ... ['rate', '8000'], # resample to 8000 Hz + ... ] + >>> + >>> # Apply effects and load data with channels_first=True + >>> waveform, sample_rate = apply_effects_file("data.wav", effects, channels_first=True) + >>> + >>> # Check the result + >>> waveform.shape + torch.Size([2, 8000]) + >>> waveform + tensor([[ 5.1151e-03, 1.8073e-02, 2.2188e-02, ..., 1.0431e-07, + -1.4761e-07, 1.8114e-07], + [-2.6924e-03, 2.1860e-03, 1.0650e-02, ..., 6.4122e-07, + -5.6159e-07, 4.8103e-07]]) + >>> sample_rate + 8000 + + Example - Apply random speed perturbation to dataset + >>> + >>> # Load data from file, apply random speed perturbation + >>> class RandomPerturbationFile(torch.utils.data.Dataset): + ... \"\"\"Given flist, apply random speed perturbation + ... + ... Suppose all the input files are at least one second long. + ... \"\"\" + ... def __init__(self, flist: List[str], sample_rate: int): + ... super().__init__() + ... self.flist = flist + ... self.sample_rate = sample_rate + ... + ... def __getitem__(self, index): + ... speed = 0.5 + 1.5 * random.randn() + ... effects = [ + ... ['gain', '-n', '-10'], # apply 10 db attenuation + ... ['remix', '-'], # merge all the channels + ... ['speed', f'{speed:.5f}'], # duration is now 0.5 ~ 2.0 seconds. + ... ['rate', f'{self.sample_rate}'], + ... ['pad', '0', '1.5'], # add 1.5 seconds silence at the end + ... ['trim', '0', '2'], # get the first 2 seconds + ... ] + ... waveform, _ = torchaudio.sox_effects.apply_effects_file( + ... self.flist[index], effects) + ... return waveform + ... + ... def __len__(self): + ... return len(self.flist) + ... + >>> dataset = RandomPerturbationFile(file_list, sample_rate=8000) + >>> loader = torch.utils.data.DataLoader(dataset, batch_size=32) + >>> for batch in loader: + >>> pass + """ + if not torch.jit.is_scripting(): + if hasattr(path, "read"): + raise RuntimeError( + "apply_effects_file function does not support file-like object. " + "Please use torchaudio.io.AudioEffector." + ) + path = os.fspath(path) + return sox_ext.apply_effects_file(path, effects, normalize, channels_first, format) diff --git a/.venv/lib/python3.11/site-packages/torchaudio/transforms/__init__.py b/.venv/lib/python3.11/site-packages/torchaudio/transforms/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1fe77865a9740ab6c88465dbe4a5a41bc445a688 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/torchaudio/transforms/__init__.py @@ -0,0 +1,75 @@ +from ._multi_channel import MVDR, PSD, RTFMVDR, SoudenMVDR +from ._transforms import ( + AddNoise, + AmplitudeToDB, + ComputeDeltas, + Convolve, + Deemphasis, + Fade, + FFTConvolve, + FrequencyMasking, + GriffinLim, + InverseMelScale, + InverseSpectrogram, + LFCC, + Loudness, + MelScale, + MelSpectrogram, + MFCC, + MuLawDecoding, + MuLawEncoding, + PitchShift, + Preemphasis, + Resample, + RNNTLoss, + SlidingWindowCmn, + SpecAugment, + SpectralCentroid, + Spectrogram, + Speed, + SpeedPerturbation, + TimeMasking, + TimeStretch, + Vad, + Vol, +) + + +__all__ = [ + "AddNoise", + "AmplitudeToDB", + "ComputeDeltas", + "Convolve", + "Deemphasis", + "Fade", + "FFTConvolve", + "FrequencyMasking", + "GriffinLim", + "InverseMelScale", + "InverseSpectrogram", + "LFCC", + "Loudness", + "MFCC", + "MVDR", + "MelScale", + "MelSpectrogram", + "MuLawDecoding", + "MuLawEncoding", + "PSD", + "PitchShift", + "Preemphasis", + "RNNTLoss", + "RTFMVDR", + "Resample", + "SlidingWindowCmn", + "SoudenMVDR", + "SpecAugment", + "SpectralCentroid", + "Spectrogram", + "Speed", + "SpeedPerturbation", + "TimeMasking", + "TimeStretch", + "Vad", + "Vol", +] diff --git a/.venv/lib/python3.11/site-packages/torchaudio/transforms/__pycache__/__init__.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/transforms/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7e2e224946372ae654d3ab7cfbcd8a0ca067ec52 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/transforms/__pycache__/__init__.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/transforms/__pycache__/_multi_channel.cpython-311.pyc b/.venv/lib/python3.11/site-packages/torchaudio/transforms/__pycache__/_multi_channel.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e9bd1e90a498ce4037652cb238d81d2d6789b49f Binary files /dev/null and b/.venv/lib/python3.11/site-packages/torchaudio/transforms/__pycache__/_multi_channel.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/torchaudio/transforms/_multi_channel.py b/.venv/lib/python3.11/site-packages/torchaudio/transforms/_multi_channel.py new file mode 100644 index 0000000000000000000000000000000000000000..4ba3db7f454058de7c0fda1d57781ed346d7a65c --- /dev/null +++ b/.venv/lib/python3.11/site-packages/torchaudio/transforms/_multi_channel.py @@ -0,0 +1,467 @@ +# -*- coding: utf-8 -*- + +import warnings +from typing import Optional, Union + +import torch +from torch import Tensor +from torchaudio import functional as F + + +__all__ = [] + + +def _get_mvdr_vector( + psd_s: torch.Tensor, + psd_n: torch.Tensor, + reference_vector: torch.Tensor, + solution: str = "ref_channel", + diagonal_loading: bool = True, + diag_eps: float = 1e-7, + eps: float = 1e-8, +) -> torch.Tensor: + r"""Compute the MVDR beamforming weights with ``solution`` argument. + + Args: + psd_s (torch.Tensor): The complex-valued power spectral density (PSD) matrix of target speech. + Tensor with dimensions `(..., freq, channel, channel)`. + psd_n (torch.Tensor): The complex-valued power spectral density (PSD) matrix of noise. + Tensor with dimensions `(..., freq, channel, channel)`. + reference_vector (torch.Tensor): one-hot reference channel matrix. + solution (str, optional): Solution to compute the MVDR beamforming weights. + Options: [``ref_channel``, ``stv_evd``, ``stv_power``]. (Default: ``ref_channel``) + diagonal_loading (bool, optional): If ``True``, enables applying diagonal loading to ``psd_n``. + (Default: ``True``) + diag_eps (float, optional): The coefficient multiplied to the identity matrix for diagonal loading. + It is only effective when ``diagonal_loading`` is set to ``True``. (Default: ``1e-7``) + eps (float, optional): Value to add to the denominator in the beamforming weight formula. + (Default: ``1e-8``) + + Returns: + torch.Tensor: the mvdr beamforming weight matrix + """ + if solution == "ref_channel": + beamform_vector = F.mvdr_weights_souden(psd_s, psd_n, reference_vector, diagonal_loading, diag_eps, eps) + else: + if solution == "stv_evd": + stv = F.rtf_evd(psd_s) + else: + stv = F.rtf_power(psd_s, psd_n, reference_vector, diagonal_loading=diagonal_loading, diag_eps=diag_eps) + beamform_vector = F.mvdr_weights_rtf(stv, psd_n, reference_vector, diagonal_loading, diag_eps, eps) + + return beamform_vector + + +class PSD(torch.nn.Module): + r"""Compute cross-channel power spectral density (PSD) matrix. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Args: + multi_mask (bool, optional): If ``True``, only accepts multi-channel Time-Frequency masks. (Default: ``False``) + normalize (bool, optional): If ``True``, normalize the mask along the time dimension. (Default: ``True``) + eps (float, optional): Value to add to the denominator in mask normalization. (Default: ``1e-15``) + """ + + def __init__(self, multi_mask: bool = False, normalize: bool = True, eps: float = 1e-15): + super().__init__() + self.multi_mask = multi_mask + self.normalize = normalize + self.eps = eps + + def forward(self, specgram: torch.Tensor, mask: Optional[torch.Tensor] = None): + """ + Args: + specgram (torch.Tensor): Multi-channel complex-valued spectrum. + Tensor with dimensions `(..., channel, freq, time)`. + mask (torch.Tensor or None, optional): Time-Frequency mask for normalization. + Tensor with dimensions `(..., freq, time)` if multi_mask is ``False`` or + with dimensions `(..., channel, freq, time)` if multi_mask is ``True``. + (Default: ``None``) + + Returns: + torch.Tensor: The complex-valued PSD matrix of the input spectrum. + Tensor with dimensions `(..., freq, channel, channel)` + """ + if mask is not None: + if self.multi_mask: + # Averaging mask along channel dimension + mask = mask.mean(dim=-3) # (..., freq, time) + psd = F.psd(specgram, mask, self.normalize, self.eps) + + return psd + + +class MVDR(torch.nn.Module): + """Minimum Variance Distortionless Response (MVDR) module that performs MVDR beamforming with Time-Frequency masks. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Based on https://github.com/espnet/espnet/blob/master/espnet2/enh/layers/beamformer.py + + We provide three solutions of MVDR beamforming. One is based on *reference channel selection* + :cite:`souden2009optimal` (``solution=ref_channel``). + + .. math:: + \\textbf{w}_{\\text{MVDR}}(f) =\ + \\frac{{{\\bf{\\Phi}_{\\textbf{NN}}^{-1}}(f){\\bf{\\Phi}_{\\textbf{SS}}}}(f)}\ + {\\text{Trace}({{{\\bf{\\Phi}_{\\textbf{NN}}^{-1}}(f) \\bf{\\Phi}_{\\textbf{SS}}}(f))}}\\bm{u} + + where :math:`\\bf{\\Phi}_{\\textbf{SS}}` and :math:`\\bf{\\Phi}_{\\textbf{NN}}` are the covariance\ + matrices of speech and noise, respectively. :math:`\\bf{u}` is an one-hot vector to determine the\ + reference channel. + + The other two solutions are based on the steering vector (``solution=stv_evd`` or ``solution=stv_power``). + + .. math:: + \\textbf{w}_{\\text{MVDR}}(f) =\ + \\frac{{{\\bf{\\Phi}_{\\textbf{NN}}^{-1}}(f){\\bm{v}}(f)}}\ + {{\\bm{v}^{\\mathsf{H}}}(f){\\bf{\\Phi}_{\\textbf{NN}}^{-1}}(f){\\bm{v}}(f)} + + where :math:`\\bm{v}` is the acoustic transfer function or the steering vector.\ + :math:`.^{\\mathsf{H}}` denotes the Hermitian Conjugate operation. + + We apply either *eigenvalue decomposition* + :cite:`higuchi2016robust` or the *power method* :cite:`mises1929praktische` to get the + steering vector from the PSD matrix of speech. + + After estimating the beamforming weight, the enhanced Short-time Fourier Transform (STFT) is obtained by + + .. math:: + \\hat{\\bf{S}} = {\\bf{w}^\\mathsf{H}}{\\bf{Y}}, {\\bf{w}} \\in \\mathbb{C}^{M \\times F} + + where :math:`\\bf{Y}` and :math:`\\hat{\\bf{S}}` are the STFT of the multi-channel noisy speech and\ + the single-channel enhanced speech, respectively. + + For online streaming audio, we provide a *recursive method* :cite:`higuchi2017online` to update the + PSD matrices of speech and noise, respectively. + + Args: + ref_channel (int, optional): Reference channel for beamforming. (Default: ``0``) + solution (str, optional): Solution to compute the MVDR beamforming weights. + Options: [``ref_channel``, ``stv_evd``, ``stv_power``]. (Default: ``ref_channel``) + multi_mask (bool, optional): If ``True``, only accepts multi-channel Time-Frequency masks. (Default: ``False``) + diagonal_loading (bool, optional): If ``True``, enables applying diagonal loading to the covariance matrix + of the noise. (Default: ``True``) + diag_eps (float, optional): The coefficient multiplied to the identity matrix for diagonal loading. + It is only effective when ``diagonal_loading`` is set to ``True``. (Default: ``1e-7``) + online (bool, optional): If ``True``, updates the MVDR beamforming weights based on + the previous covarience matrices. (Default: ``False``) + + Note: + To improve the numerical stability, the input spectrogram will be converted to double precision + (``torch.complex128`` or ``torch.cdouble``) dtype for internal computation. The output spectrogram + is converted to the dtype of the input spectrogram to be compatible with other modules. + + Note: + If you use ``stv_evd`` solution, the gradient of the same input may not be identical if the + eigenvalues of the PSD matrix are not distinct (i.e. some eigenvalues are close or identical). + """ + + def __init__( + self, + ref_channel: int = 0, + solution: str = "ref_channel", + multi_mask: bool = False, + diag_loading: bool = True, + diag_eps: float = 1e-7, + online: bool = False, + ): + super().__init__() + if solution not in [ + "ref_channel", + "stv_evd", + "stv_power", + ]: + raise ValueError( + '`solution` must be one of ["ref_channel", "stv_evd", "stv_power"]. Given {}'.format(solution) + ) + self.ref_channel = ref_channel + self.solution = solution + self.multi_mask = multi_mask + self.diag_loading = diag_loading + self.diag_eps = diag_eps + self.online = online + self.psd = PSD(multi_mask) + + psd_s: torch.Tensor = torch.zeros(1) + psd_n: torch.Tensor = torch.zeros(1) + mask_sum_s: torch.Tensor = torch.zeros(1) + mask_sum_n: torch.Tensor = torch.zeros(1) + self.register_buffer("psd_s", psd_s) + self.register_buffer("psd_n", psd_n) + self.register_buffer("mask_sum_s", mask_sum_s) + self.register_buffer("mask_sum_n", mask_sum_n) + + def _get_updated_mvdr_vector( + self, + psd_s: torch.Tensor, + psd_n: torch.Tensor, + mask_s: torch.Tensor, + mask_n: torch.Tensor, + reference_vector: torch.Tensor, + solution: str = "ref_channel", + diagonal_loading: bool = True, + diag_eps: float = 1e-7, + eps: float = 1e-8, + ) -> torch.Tensor: + r"""Recursively update the MVDR beamforming vector. + + Args: + psd_s (torch.Tensor): The complex-valued power spectral density (PSD) matrix of target speech. + Tensor with dimensions `(..., freq, channel, channel)`. + psd_n (torch.Tensor): The complex-valued power spectral density (PSD) matrix of noise. + Tensor with dimensions `(..., freq, channel, channel)`. + mask_s (torch.Tensor): Time-Frequency mask of the target speech. + Tensor with dimensions `(..., freq, time)` if multi_mask is ``False`` + or with dimensions `(..., channel, freq, time)` if multi_mask is ``True``. + mask_n (torch.Tensor or None, optional): Time-Frequency mask of the noise. + Tensor with dimensions `(..., freq, time)` if multi_mask is ``False`` + or with dimensions `(..., channel, freq, time)` if multi_mask is ``True``. + reference_vector (torch.Tensor): One-hot reference channel matrix. + solution (str, optional): Solution to compute the MVDR beamforming weights. + Options: [``ref_channel``, ``stv_evd``, ``stv_power``]. (Default: ``ref_channel``) + diagonal_loading (bool, optional): If ``True``, enables applying diagonal loading to ``psd_n``. + (Default: ``True``) + diag_eps (float, optional): The coefficient multiplied to the identity matrix for diagonal loading. + It is only effective when ``diagonal_loading`` is set to ``True``. (Default: ``1e-7``) + eps (float, optional): Value to add to the denominator in the beamforming weight formula. + (Default: ``1e-8``) + + Returns: + torch.Tensor: The MVDR beamforming weight matrix. + """ + if self.multi_mask: + # Averaging mask along channel dimension + mask_s = mask_s.mean(dim=-3) # (..., freq, time) + mask_n = mask_n.mean(dim=-3) # (..., freq, time) + if self.psd_s.ndim == 1: + self.psd_s = psd_s + self.psd_n = psd_n + self.mask_sum_s = mask_s.sum(dim=-1) + self.mask_sum_n = mask_n.sum(dim=-1) + return _get_mvdr_vector(psd_s, psd_n, reference_vector, solution, diagonal_loading, diag_eps, eps) + else: + psd_s = self._get_updated_psd_speech(psd_s, mask_s) + psd_n = self._get_updated_psd_noise(psd_n, mask_n) + self.psd_s = psd_s + self.psd_n = psd_n + self.mask_sum_s = self.mask_sum_s + mask_s.sum(dim=-1) + self.mask_sum_n = self.mask_sum_n + mask_n.sum(dim=-1) + return _get_mvdr_vector(psd_s, psd_n, reference_vector, solution, diagonal_loading, diag_eps, eps) + + def _get_updated_psd_speech(self, psd_s: torch.Tensor, mask_s: torch.Tensor) -> torch.Tensor: + r"""Update psd of speech recursively. + + Args: + psd_s (torch.Tensor): The complex-valued power spectral density (PSD) matrix of target speech. + Tensor with dimensions `(..., freq, channel, channel)`. + mask_s (torch.Tensor): Time-Frequency mask of the target speech. + Tensor with dimensions `(..., freq, time)`. + + Returns: + torch.Tensor: The updated PSD matrix of target speech. + """ + numerator = self.mask_sum_s / (self.mask_sum_s + mask_s.sum(dim=-1)) + denominator = 1 / (self.mask_sum_s + mask_s.sum(dim=-1)) + psd_s = self.psd_s * numerator[..., None, None] + psd_s * denominator[..., None, None] + return psd_s + + def _get_updated_psd_noise(self, psd_n: torch.Tensor, mask_n: torch.Tensor) -> torch.Tensor: + r"""Update psd of noise recursively. + + Args: + psd_n (torch.Tensor): The complex-valued power spectral density (PSD) matrix of noise. + Tensor with dimensions `(..., freq, channel, channel)`. + mask_n (torch.Tensor or None, optional): Time-Frequency mask of the noise. + Tensor with dimensions `(..., freq, time)`. + + Returns: + torch.Tensor: The updated PSD matrix of noise. + """ + numerator = self.mask_sum_n / (self.mask_sum_n + mask_n.sum(dim=-1)) + denominator = 1 / (self.mask_sum_n + mask_n.sum(dim=-1)) + psd_n = self.psd_n * numerator[..., None, None] + psd_n * denominator[..., None, None] + return psd_n + + def forward( + self, specgram: torch.Tensor, mask_s: torch.Tensor, mask_n: Optional[torch.Tensor] = None + ) -> torch.Tensor: + """Perform MVDR beamforming. + + Args: + specgram (torch.Tensor): Multi-channel complex-valued spectrum. + Tensor with dimensions `(..., channel, freq, time)` + mask_s (torch.Tensor): Time-Frequency mask of target speech. + Tensor with dimensions `(..., freq, time)` if multi_mask is ``False`` + or with dimensions `(..., channel, freq, time)` if multi_mask is ``True``. + mask_n (torch.Tensor or None, optional): Time-Frequency mask of noise. + Tensor with dimensions `(..., freq, time)` if multi_mask is ``False`` + or with dimensions `(..., channel, freq, time)` if multi_mask is ``True``. + (Default: None) + + Returns: + torch.Tensor: Single-channel complex-valued enhanced spectrum with dimensions `(..., freq, time)`. + """ + dtype = specgram.dtype + if specgram.ndim < 3: + raise ValueError(f"Expected at least 3D tensor (..., channel, freq, time). Found: {specgram.shape}") + if not specgram.is_complex(): + raise ValueError( + f"The type of ``specgram`` tensor must be ``torch.cfloat`` or ``torch.cdouble``.\ + Found: {specgram.dtype}" + ) + if specgram.dtype == torch.cfloat: + specgram = specgram.cdouble() # Convert specgram to ``torch.cdouble``. + + if mask_n is None: + warnings.warn("``mask_n`` is not provided, use ``1 - mask_s`` as ``mask_n``.") + mask_n = 1 - mask_s + + psd_s = self.psd(specgram, mask_s) # (..., freq, time, channel, channel) + psd_n = self.psd(specgram, mask_n) # (..., freq, time, channel, channel) + + u = torch.zeros(specgram.size()[:-2], device=specgram.device, dtype=torch.cdouble) # (..., channel) + u[..., self.ref_channel].fill_(1) + + if self.online: + w_mvdr = self._get_updated_mvdr_vector( + psd_s, psd_n, mask_s, mask_n, u, self.solution, self.diag_loading, self.diag_eps + ) + else: + w_mvdr = _get_mvdr_vector(psd_s, psd_n, u, self.solution, self.diag_loading, self.diag_eps) + + specgram_enhanced = F.apply_beamforming(w_mvdr, specgram) + + return specgram_enhanced.to(dtype) + + +class RTFMVDR(torch.nn.Module): + r"""Minimum Variance Distortionless Response (*MVDR* :cite:`capon1969high`) module + based on the relative transfer function (RTF) and power spectral density (PSD) matrix of noise. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Given the multi-channel complex-valued spectrum :math:`\textbf{Y}`, the relative transfer function (RTF) matrix + or the steering vector of target speech :math:`\bm{v}`, the PSD matrix of noise :math:`\bf{\Phi}_{\textbf{NN}}`, and + a one-hot vector that represents the reference channel :math:`\bf{u}`, the module computes the single-channel + complex-valued spectrum of the enhanced speech :math:`\hat{\textbf{S}}`. The formula is defined as: + + .. math:: + \hat{\textbf{S}}(f) = \textbf{w}_{\text{bf}}(f)^{\mathsf{H}} \textbf{Y}(f) + + where :math:`\textbf{w}_{\text{bf}}(f)` is the MVDR beamforming weight for the :math:`f`-th frequency bin, + :math:`(.)^{\mathsf{H}}` denotes the Hermitian Conjugate operation. + + The beamforming weight is computed by: + + .. math:: + \textbf{w}_{\text{MVDR}}(f) = + \frac{{{\bf{\Phi}_{\textbf{NN}}^{-1}}(f){\bm{v}}(f)}} + {{\bm{v}^{\mathsf{H}}}(f){\bf{\Phi}_{\textbf{NN}}^{-1}}(f){\bm{v}}(f)} + """ + + def forward( + self, + specgram: Tensor, + rtf: Tensor, + psd_n: Tensor, + reference_channel: Union[int, Tensor], + diagonal_loading: bool = True, + diag_eps: float = 1e-7, + eps: float = 1e-8, + ) -> Tensor: + """ + Args: + specgram (torch.Tensor): Multi-channel complex-valued spectrum. + Tensor with dimensions `(..., channel, freq, time)` + rtf (torch.Tensor): The complex-valued RTF vector of target speech. + Tensor with dimensions `(..., freq, channel)`. + psd_n (torch.Tensor): The complex-valued power spectral density (PSD) matrix of noise. + Tensor with dimensions `(..., freq, channel, channel)`. + reference_channel (int or torch.Tensor): Specifies the reference channel. + If the dtype is ``int``, it represents the reference channel index. + If the dtype is ``torch.Tensor``, its shape is `(..., channel)`, where the ``channel`` dimension + is one-hot. + diagonal_loading (bool, optional): If ``True``, enables applying diagonal loading to ``psd_n``. + (Default: ``True``) + diag_eps (float, optional): The coefficient multiplied to the identity matrix for diagonal loading. + It is only effective when ``diagonal_loading`` is set to ``True``. (Default: ``1e-7``) + eps (float, optional): Value to add to the denominator in the beamforming weight formula. + (Default: ``1e-8``) + + Returns: + torch.Tensor: Single-channel complex-valued enhanced spectrum with dimensions `(..., freq, time)`. + """ + w_mvdr = F.mvdr_weights_rtf(rtf, psd_n, reference_channel, diagonal_loading, diag_eps, eps) + spectrum_enhanced = F.apply_beamforming(w_mvdr, specgram) + return spectrum_enhanced + + +class SoudenMVDR(torch.nn.Module): + r"""Minimum Variance Distortionless Response (*MVDR* :cite:`capon1969high`) module + based on the method proposed by *Souden et, al.* :cite:`souden2009optimal`. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Given the multi-channel complex-valued spectrum :math:`\textbf{Y}`, the power spectral density (PSD) matrix + of target speech :math:`\bf{\Phi}_{\textbf{SS}}`, the PSD matrix of noise :math:`\bf{\Phi}_{\textbf{NN}}`, and + a one-hot vector that represents the reference channel :math:`\bf{u}`, the module computes the single-channel + complex-valued spectrum of the enhanced speech :math:`\hat{\textbf{S}}`. The formula is defined as: + + .. math:: + \hat{\textbf{S}}(f) = \textbf{w}_{\text{bf}}(f)^{\mathsf{H}} \textbf{Y}(f) + + where :math:`\textbf{w}_{\text{bf}}(f)` is the MVDR beamforming weight for the :math:`f`-th frequency bin. + + The beamforming weight is computed by: + + .. math:: + \textbf{w}_{\text{MVDR}}(f) = + \frac{{{\bf{\Phi}_{\textbf{NN}}^{-1}}(f){\bf{\Phi}_{\textbf{SS}}}}(f)} + {\text{Trace}({{{\bf{\Phi}_{\textbf{NN}}^{-1}}(f) \bf{\Phi}_{\textbf{SS}}}(f))}}\bm{u} + """ + + def forward( + self, + specgram: Tensor, + psd_s: Tensor, + psd_n: Tensor, + reference_channel: Union[int, Tensor], + diagonal_loading: bool = True, + diag_eps: float = 1e-7, + eps: float = 1e-8, + ) -> torch.Tensor: + """ + Args: + specgram (torch.Tensor): Multi-channel complex-valued spectrum. + Tensor with dimensions `(..., channel, freq, time)`. + psd_s (torch.Tensor): The complex-valued power spectral density (PSD) matrix of target speech. + Tensor with dimensions `(..., freq, channel, channel)`. + psd_n (torch.Tensor): The complex-valued power spectral density (PSD) matrix of noise. + Tensor with dimensions `(..., freq, channel, channel)`. + reference_channel (int or torch.Tensor): Specifies the reference channel. + If the dtype is ``int``, it represents the reference channel index. + If the dtype is ``torch.Tensor``, its shape is `(..., channel)`, where the ``channel`` dimension + is one-hot. + diagonal_loading (bool, optional): If ``True``, enables applying diagonal loading to ``psd_n``. + (Default: ``True``) + diag_eps (float, optional): The coefficient multiplied to the identity matrix for diagonal loading. + It is only effective when ``diagonal_loading`` is set to ``True``. (Default: ``1e-7``) + eps (float, optional): Value to add to the denominator in the beamforming weight formula. + (Default: ``1e-8``) + + Returns: + torch.Tensor: Single-channel complex-valued enhanced spectrum with dimensions `(..., freq, time)`. + """ + w_mvdr = F.mvdr_weights_souden(psd_s, psd_n, reference_channel, diagonal_loading, diag_eps, eps) + spectrum_enhanced = F.apply_beamforming(w_mvdr, specgram) + return spectrum_enhanced diff --git a/.venv/lib/python3.11/site-packages/torchaudio/transforms/_transforms.py b/.venv/lib/python3.11/site-packages/torchaudio/transforms/_transforms.py new file mode 100644 index 0000000000000000000000000000000000000000..802cbd3d7783d6117fa2d5361d55db567aba43d5 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/torchaudio/transforms/_transforms.py @@ -0,0 +1,2137 @@ +# -*- coding: utf-8 -*- + +import math +import warnings +from typing import Callable, Optional, Sequence, Tuple, Union + +import torch +from torch import Tensor +from torch.nn.modules.lazy import LazyModuleMixin +from torch.nn.parameter import UninitializedParameter + +from torchaudio import functional as F +from torchaudio.functional.functional import ( + _apply_sinc_resample_kernel, + _check_convolve_mode, + _fix_waveform_shape, + _get_sinc_resample_kernel, + _stretch_waveform, +) + +__all__ = [] + + +class Spectrogram(torch.nn.Module): + r"""Create a spectrogram from a audio signal. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Args: + n_fft (int, optional): Size of FFT, creates ``n_fft // 2 + 1`` bins. (Default: ``400``) + win_length (int or None, optional): Window size. (Default: ``n_fft``) + hop_length (int or None, optional): Length of hop between STFT windows. (Default: ``win_length // 2``) + pad (int, optional): Two sided padding of signal. (Default: ``0``) + window_fn (Callable[..., Tensor], optional): A function to create a window tensor + that is applied/multiplied to each frame/window. (Default: ``torch.hann_window``) + power (float or None, optional): Exponent for the magnitude spectrogram, + (must be > 0) e.g., 1 for magnitude, 2 for power, etc. + If None, then the complex spectrum is returned instead. (Default: ``2``) + normalized (bool or str, optional): Whether to normalize by magnitude after stft. If input is str, choices are + ``"window"`` and ``"frame_length"``, if specific normalization type is desirable. ``True`` maps to + ``"window"``. (Default: ``False``) + wkwargs (dict or None, optional): Arguments for window function. (Default: ``None``) + center (bool, optional): whether to pad :attr:`waveform` on both sides so + that the :math:`t`-th frame is centered at time :math:`t \times \text{hop\_length}`. + (Default: ``True``) + pad_mode (string, optional): controls the padding method used when + :attr:`center` is ``True``. (Default: ``"reflect"``) + onesided (bool, optional): controls whether to return half of results to + avoid redundancy (Default: ``True``) + return_complex (bool, optional): + Deprecated and not used. + + Example + >>> waveform, sample_rate = torchaudio.load("test.wav", normalize=True) + >>> transform = torchaudio.transforms.Spectrogram(n_fft=800) + >>> spectrogram = transform(waveform) + + """ + __constants__ = ["n_fft", "win_length", "hop_length", "pad", "power", "normalized"] + + def __init__( + self, + n_fft: int = 400, + win_length: Optional[int] = None, + hop_length: Optional[int] = None, + pad: int = 0, + window_fn: Callable[..., Tensor] = torch.hann_window, + power: Optional[float] = 2.0, + normalized: Union[bool, str] = False, + wkwargs: Optional[dict] = None, + center: bool = True, + pad_mode: str = "reflect", + onesided: bool = True, + return_complex: Optional[bool] = None, + ) -> None: + super(Spectrogram, self).__init__() + torch._C._log_api_usage_once("torchaudio.transforms.Spectrogram") + self.n_fft = n_fft + # number of FFT bins. the returned STFT result will have n_fft // 2 + 1 + # number of frequencies due to onesided=True in torch.stft + self.win_length = win_length if win_length is not None else n_fft + self.hop_length = hop_length if hop_length is not None else self.win_length // 2 + window = window_fn(self.win_length) if wkwargs is None else window_fn(self.win_length, **wkwargs) + self.register_buffer("window", window) + self.pad = pad + self.power = power + self.normalized = normalized + self.center = center + self.pad_mode = pad_mode + self.onesided = onesided + if return_complex is not None: + warnings.warn( + "`return_complex` argument is now deprecated and is not effective." + "`torchaudio.transforms.Spectrogram(power=None)` always returns a tensor with " + "complex dtype. Please remove the argument in the function call." + ) + + def forward(self, waveform: Tensor) -> Tensor: + r""" + Args: + waveform (Tensor): Tensor of audio of dimension (..., time). + + Returns: + Tensor: Dimension (..., freq, time), where freq is + ``n_fft // 2 + 1`` where ``n_fft`` is the number of + Fourier bins, and time is the number of window hops (n_frame). + """ + return F.spectrogram( + waveform, + self.pad, + self.window, + self.n_fft, + self.hop_length, + self.win_length, + self.power, + self.normalized, + self.center, + self.pad_mode, + self.onesided, + ) + + +class InverseSpectrogram(torch.nn.Module): + r"""Create an inverse spectrogram to recover an audio signal from a spectrogram. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Args: + n_fft (int, optional): Size of FFT, creates ``n_fft // 2 + 1`` bins. (Default: ``400``) + win_length (int or None, optional): Window size. (Default: ``n_fft``) + hop_length (int or None, optional): Length of hop between STFT windows. (Default: ``win_length // 2``) + pad (int, optional): Two sided padding of signal. (Default: ``0``) + window_fn (Callable[..., Tensor], optional): A function to create a window tensor + that is applied/multiplied to each frame/window. (Default: ``torch.hann_window``) + normalized (bool or str, optional): Whether the stft output was normalized by magnitude. If input is str, + choices are ``"window"`` and ``"frame_length"``, dependent on normalization mode. ``True`` maps to + ``"window"``. (Default: ``False``) + wkwargs (dict or None, optional): Arguments for window function. (Default: ``None``) + center (bool, optional): whether the signal in spectrogram was padded on both sides so + that the :math:`t`-th frame is centered at time :math:`t \times \text{hop\_length}`. + (Default: ``True``) + pad_mode (string, optional): controls the padding method used when + :attr:`center` is ``True``. (Default: ``"reflect"``) + onesided (bool, optional): controls whether spectrogram was used to return half of results to + avoid redundancy (Default: ``True``) + + Example + >>> batch, freq, time = 2, 257, 100 + >>> length = 25344 + >>> spectrogram = torch.randn(batch, freq, time, dtype=torch.cdouble) + >>> transform = transforms.InverseSpectrogram(n_fft=512) + >>> waveform = transform(spectrogram, length) + """ + __constants__ = ["n_fft", "win_length", "hop_length", "pad", "power", "normalized"] + + def __init__( + self, + n_fft: int = 400, + win_length: Optional[int] = None, + hop_length: Optional[int] = None, + pad: int = 0, + window_fn: Callable[..., Tensor] = torch.hann_window, + normalized: Union[bool, str] = False, + wkwargs: Optional[dict] = None, + center: bool = True, + pad_mode: str = "reflect", + onesided: bool = True, + ) -> None: + super(InverseSpectrogram, self).__init__() + self.n_fft = n_fft + # number of FFT bins. the returned STFT result will have n_fft // 2 + 1 + # number of frequencies due to onesided=True in torch.stft + self.win_length = win_length if win_length is not None else n_fft + self.hop_length = hop_length if hop_length is not None else self.win_length // 2 + window = window_fn(self.win_length) if wkwargs is None else window_fn(self.win_length, **wkwargs) + self.register_buffer("window", window) + self.pad = pad + self.normalized = normalized + self.center = center + self.pad_mode = pad_mode + self.onesided = onesided + + def forward(self, spectrogram: Tensor, length: Optional[int] = None) -> Tensor: + r""" + Args: + spectrogram (Tensor): Complex tensor of audio of dimension (..., freq, time). + length (int or None, optional): The output length of the waveform. + + Returns: + Tensor: Dimension (..., time), Least squares estimation of the original signal. + """ + return F.inverse_spectrogram( + spectrogram, + length, + self.pad, + self.window, + self.n_fft, + self.hop_length, + self.win_length, + self.normalized, + self.center, + self.pad_mode, + self.onesided, + ) + + +class GriffinLim(torch.nn.Module): + r"""Compute waveform from a linear scale magnitude spectrogram using the Griffin-Lim transformation. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Implementation ported from + *librosa* :cite:`brian_mcfee-proc-scipy-2015`, *A fast Griffin-Lim algorithm* :cite:`6701851` + and *Signal estimation from modified short-time Fourier transform* :cite:`1172092`. + + Args: + n_fft (int, optional): Size of FFT, creates ``n_fft // 2 + 1`` bins. (Default: ``400``) + n_iter (int, optional): Number of iteration for phase recovery process. (Default: ``32``) + win_length (int or None, optional): Window size. (Default: ``n_fft``) + hop_length (int or None, optional): Length of hop between STFT windows. (Default: ``win_length // 2``) + window_fn (Callable[..., Tensor], optional): A function to create a window tensor + that is applied/multiplied to each frame/window. (Default: ``torch.hann_window``) + power (float, optional): Exponent for the magnitude spectrogram, + (must be > 0) e.g., 1 for magnitude, 2 for power, etc. (Default: ``2``) + wkwargs (dict or None, optional): Arguments for window function. (Default: ``None``) + momentum (float, optional): The momentum parameter for fast Griffin-Lim. + Setting this to 0 recovers the original Griffin-Lim method. + Values near 1 can lead to faster convergence, but above 1 may not converge. (Default: ``0.99``) + length (int, optional): Array length of the expected output. (Default: ``None``) + rand_init (bool, optional): Initializes phase randomly if True and to zero otherwise. (Default: ``True``) + + Example + >>> batch, freq, time = 2, 257, 100 + >>> spectrogram = torch.randn(batch, freq, time) + >>> transform = transforms.GriffinLim(n_fft=512) + >>> waveform = transform(spectrogram) + """ + __constants__ = ["n_fft", "n_iter", "win_length", "hop_length", "power", "length", "momentum", "rand_init"] + + def __init__( + self, + n_fft: int = 400, + n_iter: int = 32, + win_length: Optional[int] = None, + hop_length: Optional[int] = None, + window_fn: Callable[..., Tensor] = torch.hann_window, + power: float = 2.0, + wkwargs: Optional[dict] = None, + momentum: float = 0.99, + length: Optional[int] = None, + rand_init: bool = True, + ) -> None: + super(GriffinLim, self).__init__() + + if not (0 <= momentum < 1): + raise ValueError("momentum must be in the range [0, 1). Found: {}".format(momentum)) + + self.n_fft = n_fft + self.n_iter = n_iter + self.win_length = win_length if win_length is not None else n_fft + self.hop_length = hop_length if hop_length is not None else self.win_length // 2 + window = window_fn(self.win_length) if wkwargs is None else window_fn(self.win_length, **wkwargs) + self.register_buffer("window", window) + self.length = length + self.power = power + self.momentum = momentum + self.rand_init = rand_init + + def forward(self, specgram: Tensor) -> Tensor: + r""" + Args: + specgram (Tensor): + A magnitude-only STFT spectrogram of dimension (..., freq, frames) + where freq is ``n_fft // 2 + 1``. + + Returns: + Tensor: waveform of (..., time), where time equals the ``length`` parameter if given. + """ + return F.griffinlim( + specgram, + self.window, + self.n_fft, + self.hop_length, + self.win_length, + self.power, + self.n_iter, + self.momentum, + self.length, + self.rand_init, + ) + + +class AmplitudeToDB(torch.nn.Module): + r"""Turn a tensor from the power/amplitude scale to the decibel scale. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + This output depends on the maximum value in the input tensor, and so + may return different values for an audio clip split into snippets vs. a + a full clip. + + Args: + stype (str, optional): scale of input tensor (``"power"`` or ``"magnitude"``). The + power being the elementwise square of the magnitude. (Default: ``"power"``) + top_db (float or None, optional): minimum negative cut-off in decibels. A reasonable + number is 80. (Default: ``None``) + + Example + >>> waveform, sample_rate = torchaudio.load("test.wav", normalize=True) + >>> transform = transforms.AmplitudeToDB(stype="amplitude", top_db=80) + >>> waveform_db = transform(waveform) + """ + __constants__ = ["multiplier", "amin", "ref_value", "db_multiplier"] + + def __init__(self, stype: str = "power", top_db: Optional[float] = None) -> None: + super(AmplitudeToDB, self).__init__() + self.stype = stype + if top_db is not None and top_db < 0: + raise ValueError("top_db must be positive value") + self.top_db = top_db + self.multiplier = 10.0 if stype == "power" else 20.0 + self.amin = 1e-10 + self.ref_value = 1.0 + self.db_multiplier = math.log10(max(self.amin, self.ref_value)) + + def forward(self, x: Tensor) -> Tensor: + r"""Numerically stable implementation from Librosa. + + https://librosa.org/doc/latest/generated/librosa.amplitude_to_db.html + + Args: + x (Tensor): Input tensor before being converted to decibel scale. + + Returns: + Tensor: Output tensor in decibel scale. + """ + return F.amplitude_to_DB(x, self.multiplier, self.amin, self.db_multiplier, self.top_db) + + +class MelScale(torch.nn.Module): + r"""Turn a normal STFT into a mel frequency STFT with triangular filter banks. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Args: + n_mels (int, optional): Number of mel filterbanks. (Default: ``128``) + sample_rate (int, optional): Sample rate of audio signal. (Default: ``16000``) + f_min (float, optional): Minimum frequency. (Default: ``0.``) + f_max (float or None, optional): Maximum frequency. (Default: ``sample_rate // 2``) + n_stft (int, optional): Number of bins in STFT. See ``n_fft`` in :class:`Spectrogram`. (Default: ``201``) + norm (str or None, optional): If ``"slaney"``, divide the triangular mel weights by the width of the mel band + (area normalization). (Default: ``None``) + mel_scale (str, optional): Scale to use: ``htk`` or ``slaney``. (Default: ``htk``) + + Example + >>> waveform, sample_rate = torchaudio.load("test.wav", normalize=True) + >>> spectrogram_transform = transforms.Spectrogram(n_fft=1024) + >>> spectrogram = spectrogram_transform(waveform) + >>> melscale_transform = transforms.MelScale(sample_rate=sample_rate, n_stft=1024 // 2 + 1) + >>> melscale_spectrogram = melscale_transform(spectrogram) + + See also: + :py:func:`torchaudio.functional.melscale_fbanks` - The function used to + generate the filter banks. + """ + __constants__ = ["n_mels", "sample_rate", "f_min", "f_max"] + + def __init__( + self, + n_mels: int = 128, + sample_rate: int = 16000, + f_min: float = 0.0, + f_max: Optional[float] = None, + n_stft: int = 201, + norm: Optional[str] = None, + mel_scale: str = "htk", + ) -> None: + super(MelScale, self).__init__() + self.n_mels = n_mels + self.sample_rate = sample_rate + self.f_max = f_max if f_max is not None else float(sample_rate // 2) + self.f_min = f_min + self.norm = norm + self.mel_scale = mel_scale + + if f_min > self.f_max: + raise ValueError("Require f_min: {} <= f_max: {}".format(f_min, self.f_max)) + + fb = F.melscale_fbanks(n_stft, self.f_min, self.f_max, self.n_mels, self.sample_rate, self.norm, self.mel_scale) + self.register_buffer("fb", fb) + + def forward(self, specgram: Tensor) -> Tensor: + r""" + Args: + specgram (Tensor): A spectrogram STFT of dimension (..., freq, time). + + Returns: + Tensor: Mel frequency spectrogram of size (..., ``n_mels``, time). + """ + + # (..., time, freq) dot (freq, n_mels) -> (..., n_mels, time) + mel_specgram = torch.matmul(specgram.transpose(-1, -2), self.fb).transpose(-1, -2) + + return mel_specgram + + +class InverseMelScale(torch.nn.Module): + r"""Estimate a STFT in normal frequency domain from mel frequency domain. + + .. devices:: CPU CUDA + + It minimizes the euclidian norm between the input mel-spectrogram and the product between + the estimated spectrogram and the filter banks using `torch.linalg.lstsq`. + + Args: + n_stft (int): Number of bins in STFT. See ``n_fft`` in :class:`Spectrogram`. + n_mels (int, optional): Number of mel filterbanks. (Default: ``128``) + sample_rate (int, optional): Sample rate of audio signal. (Default: ``16000``) + f_min (float, optional): Minimum frequency. (Default: ``0.``) + f_max (float or None, optional): Maximum frequency. (Default: ``sample_rate // 2``) + norm (str or None, optional): If "slaney", divide the triangular mel weights by the width of the mel band + (area normalization). (Default: ``None``) + mel_scale (str, optional): Scale to use: ``htk`` or ``slaney``. (Default: ``htk``) + driver (str, optional): Name of the LAPACK/MAGMA method to be used for `torch.lstsq`. + For CPU inputs the valid values are ``"gels"``, ``"gelsy"``, ``"gelsd"``, ``"gelss"``. + For CUDA input, the only valid driver is ``"gels"``, which assumes that A is full-rank. + (Default: ``"gels``) + + Example + >>> waveform, sample_rate = torchaudio.load("test.wav", normalize=True) + >>> mel_spectrogram_transform = transforms.MelSpectrogram(sample_rate, n_fft=1024) + >>> mel_spectrogram = mel_spectrogram_transform(waveform) + >>> inverse_melscale_transform = transforms.InverseMelScale(n_stft=1024 // 2 + 1) + >>> spectrogram = inverse_melscale_transform(mel_spectrogram) + """ + __constants__ = [ + "n_stft", + "n_mels", + "sample_rate", + "f_min", + "f_max", + ] + + def __init__( + self, + n_stft: int, + n_mels: int = 128, + sample_rate: int = 16000, + f_min: float = 0.0, + f_max: Optional[float] = None, + norm: Optional[str] = None, + mel_scale: str = "htk", + driver: str = "gels", + ) -> None: + super(InverseMelScale, self).__init__() + self.n_mels = n_mels + self.sample_rate = sample_rate + self.f_max = f_max or float(sample_rate // 2) + self.f_min = f_min + self.driver = driver + + if f_min > self.f_max: + raise ValueError("Require f_min: {} <= f_max: {}".format(f_min, self.f_max)) + + if driver not in ["gels", "gelsy", "gelsd", "gelss"]: + raise ValueError(f'driver must be one of ["gels", "gelsy", "gelsd", "gelss"]. Found {driver}.') + + fb = F.melscale_fbanks(n_stft, self.f_min, self.f_max, self.n_mels, self.sample_rate, norm, mel_scale) + self.register_buffer("fb", fb) + + def forward(self, melspec: Tensor) -> Tensor: + r""" + Args: + melspec (Tensor): A Mel frequency spectrogram of dimension (..., ``n_mels``, time) + + Returns: + Tensor: Linear scale spectrogram of size (..., freq, time) + """ + # pack batch + shape = melspec.size() + melspec = melspec.view(-1, shape[-2], shape[-1]) + + n_mels, time = shape[-2], shape[-1] + freq, _ = self.fb.size() # (freq, n_mels) + if self.n_mels != n_mels: + raise ValueError("Expected an input with {} mel bins. Found: {}".format(self.n_mels, n_mels)) + + specgram = torch.relu(torch.linalg.lstsq(self.fb.transpose(-1, -2)[None], melspec, driver=self.driver).solution) + + # unpack batch + specgram = specgram.view(shape[:-2] + (freq, time)) + return specgram + + +class MelSpectrogram(torch.nn.Module): + r"""Create MelSpectrogram for a raw audio signal. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + This is a composition of :py:func:`torchaudio.transforms.Spectrogram` + and :py:func:`torchaudio.transforms.MelScale`. + + Sources + * https://gist.github.com/kastnerkyle/179d6e9a88202ab0a2fe + * https://timsainb.github.io/spectrograms-mfccs-and-inversion-in-python.html + * http://haythamfayek.com/2016/04/21/speech-processing-for-machine-learning.html + + Args: + sample_rate (int, optional): Sample rate of audio signal. (Default: ``16000``) + n_fft (int, optional): Size of FFT, creates ``n_fft // 2 + 1`` bins. (Default: ``400``) + win_length (int or None, optional): Window size. (Default: ``n_fft``) + hop_length (int or None, optional): Length of hop between STFT windows. (Default: ``win_length // 2``) + f_min (float, optional): Minimum frequency. (Default: ``0.``) + f_max (float or None, optional): Maximum frequency. (Default: ``None``) + pad (int, optional): Two sided padding of signal. (Default: ``0``) + n_mels (int, optional): Number of mel filterbanks. (Default: ``128``) + window_fn (Callable[..., Tensor], optional): A function to create a window tensor + that is applied/multiplied to each frame/window. (Default: ``torch.hann_window``) + power (float, optional): Exponent for the magnitude spectrogram, + (must be > 0) e.g., 1 for magnitude, 2 for power, etc. (Default: ``2``) + normalized (bool, optional): Whether to normalize by magnitude after stft. (Default: ``False``) + wkwargs (Dict[..., ...] or None, optional): Arguments for window function. (Default: ``None``) + center (bool, optional): whether to pad :attr:`waveform` on both sides so + that the :math:`t`-th frame is centered at time :math:`t \times \text{hop\_length}`. + (Default: ``True``) + pad_mode (string, optional): controls the padding method used when + :attr:`center` is ``True``. (Default: ``"reflect"``) + onesided: Deprecated and unused. + norm (str or None, optional): If "slaney", divide the triangular mel weights by the width of the mel band + (area normalization). (Default: ``None``) + mel_scale (str, optional): Scale to use: ``htk`` or ``slaney``. (Default: ``htk``) + + Example + >>> waveform, sample_rate = torchaudio.load("test.wav", normalize=True) + >>> transform = transforms.MelSpectrogram(sample_rate) + >>> mel_specgram = transform(waveform) # (channel, n_mels, time) + + See also: + :py:func:`torchaudio.functional.melscale_fbanks` - The function used to + generate the filter banks. + """ + __constants__ = ["sample_rate", "n_fft", "win_length", "hop_length", "pad", "n_mels", "f_min"] + + def __init__( + self, + sample_rate: int = 16000, + n_fft: int = 400, + win_length: Optional[int] = None, + hop_length: Optional[int] = None, + f_min: float = 0.0, + f_max: Optional[float] = None, + pad: int = 0, + n_mels: int = 128, + window_fn: Callable[..., Tensor] = torch.hann_window, + power: float = 2.0, + normalized: bool = False, + wkwargs: Optional[dict] = None, + center: bool = True, + pad_mode: str = "reflect", + onesided: Optional[bool] = None, + norm: Optional[str] = None, + mel_scale: str = "htk", + ) -> None: + super(MelSpectrogram, self).__init__() + torch._C._log_api_usage_once("torchaudio.transforms.MelSpectrogram") + + if onesided is not None: + warnings.warn( + "Argument 'onesided' has been deprecated and has no influence on the behavior of this module." + ) + + self.sample_rate = sample_rate + self.n_fft = n_fft + self.win_length = win_length if win_length is not None else n_fft + self.hop_length = hop_length if hop_length is not None else self.win_length // 2 + self.pad = pad + self.power = power + self.normalized = normalized + self.n_mels = n_mels # number of mel frequency bins + self.f_max = f_max + self.f_min = f_min + self.spectrogram = Spectrogram( + n_fft=self.n_fft, + win_length=self.win_length, + hop_length=self.hop_length, + pad=self.pad, + window_fn=window_fn, + power=self.power, + normalized=self.normalized, + wkwargs=wkwargs, + center=center, + pad_mode=pad_mode, + onesided=True, + ) + self.mel_scale = MelScale( + self.n_mels, self.sample_rate, self.f_min, self.f_max, self.n_fft // 2 + 1, norm, mel_scale + ) + + def forward(self, waveform: Tensor) -> Tensor: + r""" + Args: + waveform (Tensor): Tensor of audio of dimension (..., time). + + Returns: + Tensor: Mel frequency spectrogram of size (..., ``n_mels``, time). + """ + specgram = self.spectrogram(waveform) + mel_specgram = self.mel_scale(specgram) + return mel_specgram + + +class MFCC(torch.nn.Module): + r"""Create the Mel-frequency cepstrum coefficients from an audio signal. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + By default, this calculates the MFCC on the DB-scaled Mel spectrogram. + This is not the textbook implementation, but is implemented here to + give consistency with librosa. + + This output depends on the maximum value in the input spectrogram, and so + may return different values for an audio clip split into snippets vs. a + a full clip. + + Args: + sample_rate (int, optional): Sample rate of audio signal. (Default: ``16000``) + n_mfcc (int, optional): Number of mfc coefficients to retain. (Default: ``40``) + dct_type (int, optional): type of DCT (discrete cosine transform) to use. (Default: ``2``) + norm (str, optional): norm to use. (Default: ``"ortho"``) + log_mels (bool, optional): whether to use log-mel spectrograms instead of db-scaled. (Default: ``False``) + melkwargs (dict or None, optional): arguments for MelSpectrogram. (Default: ``None``) + + Example + >>> waveform, sample_rate = torchaudio.load("test.wav", normalize=True) + >>> transform = transforms.MFCC( + >>> sample_rate=sample_rate, + >>> n_mfcc=13, + >>> melkwargs={"n_fft": 400, "hop_length": 160, "n_mels": 23, "center": False}, + >>> ) + >>> mfcc = transform(waveform) + + See also: + :py:func:`torchaudio.functional.melscale_fbanks` - The function used to + generate the filter banks. + """ + __constants__ = ["sample_rate", "n_mfcc", "dct_type", "top_db", "log_mels"] + + def __init__( + self, + sample_rate: int = 16000, + n_mfcc: int = 40, + dct_type: int = 2, + norm: str = "ortho", + log_mels: bool = False, + melkwargs: Optional[dict] = None, + ) -> None: + super(MFCC, self).__init__() + supported_dct_types = [2] + if dct_type not in supported_dct_types: + raise ValueError("DCT type not supported: {}".format(dct_type)) + self.sample_rate = sample_rate + self.n_mfcc = n_mfcc + self.dct_type = dct_type + self.norm = norm + self.top_db = 80.0 + self.amplitude_to_DB = AmplitudeToDB("power", self.top_db) + + melkwargs = melkwargs or {} + self.MelSpectrogram = MelSpectrogram(sample_rate=self.sample_rate, **melkwargs) + + if self.n_mfcc > self.MelSpectrogram.n_mels: + raise ValueError("Cannot select more MFCC coefficients than # mel bins") + dct_mat = F.create_dct(self.n_mfcc, self.MelSpectrogram.n_mels, self.norm) + self.register_buffer("dct_mat", dct_mat) + self.log_mels = log_mels + + def forward(self, waveform: Tensor) -> Tensor: + r""" + Args: + waveform (Tensor): Tensor of audio of dimension (..., time). + + Returns: + Tensor: specgram_mel_db of size (..., ``n_mfcc``, time). + """ + mel_specgram = self.MelSpectrogram(waveform) + if self.log_mels: + log_offset = 1e-6 + mel_specgram = torch.log(mel_specgram + log_offset) + else: + mel_specgram = self.amplitude_to_DB(mel_specgram) + + # (..., time, n_mels) dot (n_mels, n_mfcc) -> (..., n_nfcc, time) + mfcc = torch.matmul(mel_specgram.transpose(-1, -2), self.dct_mat).transpose(-1, -2) + return mfcc + + +class LFCC(torch.nn.Module): + r"""Create the linear-frequency cepstrum coefficients from an audio signal. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + By default, this calculates the LFCC on the DB-scaled linear filtered spectrogram. + This is not the textbook implementation, but is implemented here to + give consistency with librosa. + + This output depends on the maximum value in the input spectrogram, and so + may return different values for an audio clip split into snippets vs. a + a full clip. + + Args: + sample_rate (int, optional): Sample rate of audio signal. (Default: ``16000``) + n_filter (int, optional): Number of linear filters to apply. (Default: ``128``) + n_lfcc (int, optional): Number of lfc coefficients to retain. (Default: ``40``) + f_min (float, optional): Minimum frequency. (Default: ``0.``) + f_max (float or None, optional): Maximum frequency. (Default: ``None``) + dct_type (int, optional): type of DCT (discrete cosine transform) to use. (Default: ``2``) + norm (str, optional): norm to use. (Default: ``"ortho"``) + log_lf (bool, optional): whether to use log-lf spectrograms instead of db-scaled. (Default: ``False``) + speckwargs (dict or None, optional): arguments for Spectrogram. (Default: ``None``) + + Example + >>> waveform, sample_rate = torchaudio.load("test.wav", normalize=True) + >>> transform = transforms.LFCC( + >>> sample_rate=sample_rate, + >>> n_lfcc=13, + >>> speckwargs={"n_fft": 400, "hop_length": 160, "center": False}, + >>> ) + >>> lfcc = transform(waveform) + + See also: + :py:func:`torchaudio.functional.linear_fbanks` - The function used to + generate the filter banks. + """ + __constants__ = ["sample_rate", "n_filter", "n_lfcc", "dct_type", "top_db", "log_lf"] + + def __init__( + self, + sample_rate: int = 16000, + n_filter: int = 128, + f_min: float = 0.0, + f_max: Optional[float] = None, + n_lfcc: int = 40, + dct_type: int = 2, + norm: str = "ortho", + log_lf: bool = False, + speckwargs: Optional[dict] = None, + ) -> None: + super(LFCC, self).__init__() + supported_dct_types = [2] + if dct_type not in supported_dct_types: + raise ValueError("DCT type not supported: {}".format(dct_type)) + self.sample_rate = sample_rate + self.f_min = f_min + self.f_max = f_max if f_max is not None else float(sample_rate // 2) + self.n_filter = n_filter + self.n_lfcc = n_lfcc + self.dct_type = dct_type + self.norm = norm + self.top_db = 80.0 + self.amplitude_to_DB = AmplitudeToDB("power", self.top_db) + + speckwargs = speckwargs or {} + self.Spectrogram = Spectrogram(**speckwargs) + + if self.n_lfcc > self.Spectrogram.n_fft: + raise ValueError("Cannot select more LFCC coefficients than # fft bins") + + filter_mat = F.linear_fbanks( + n_freqs=self.Spectrogram.n_fft // 2 + 1, + f_min=self.f_min, + f_max=self.f_max, + n_filter=self.n_filter, + sample_rate=self.sample_rate, + ) + self.register_buffer("filter_mat", filter_mat) + + dct_mat = F.create_dct(self.n_lfcc, self.n_filter, self.norm) + self.register_buffer("dct_mat", dct_mat) + self.log_lf = log_lf + + def forward(self, waveform: Tensor) -> Tensor: + r""" + Args: + waveform (Tensor): Tensor of audio of dimension (..., time). + + Returns: + Tensor: Linear Frequency Cepstral Coefficients of size (..., ``n_lfcc``, time). + """ + specgram = self.Spectrogram(waveform) + + # (..., time, freq) dot (freq, n_filter) -> (..., n_filter, time) + specgram = torch.matmul(specgram.transpose(-1, -2), self.filter_mat).transpose(-1, -2) + + if self.log_lf: + log_offset = 1e-6 + specgram = torch.log(specgram + log_offset) + else: + specgram = self.amplitude_to_DB(specgram) + + # (..., time, n_filter) dot (n_filter, n_lfcc) -> (..., n_lfcc, time) + lfcc = torch.matmul(specgram.transpose(-1, -2), self.dct_mat).transpose(-1, -2) + return lfcc + + +class MuLawEncoding(torch.nn.Module): + r"""Encode signal based on mu-law companding. + + .. devices:: CPU CUDA + + .. properties:: TorchScript + + For more info see the + `Wikipedia Entry `_ + + This algorithm assumes the signal has been scaled to between -1 and 1 and + returns a signal encoded with values from 0 to quantization_channels - 1 + + Args: + quantization_channels (int, optional): Number of channels. (Default: ``256``) + + Example + >>> waveform, sample_rate = torchaudio.load("test.wav", normalize=True) + >>> transform = torchaudio.transforms.MuLawEncoding(quantization_channels=512) + >>> mulawtrans = transform(waveform) + + """ + __constants__ = ["quantization_channels"] + + def __init__(self, quantization_channels: int = 256) -> None: + super(MuLawEncoding, self).__init__() + self.quantization_channels = quantization_channels + + def forward(self, x: Tensor) -> Tensor: + r""" + Args: + x (Tensor): A signal to be encoded. + + Returns: + Tensor: An encoded signal. + """ + return F.mu_law_encoding(x, self.quantization_channels) + + +class MuLawDecoding(torch.nn.Module): + r"""Decode mu-law encoded signal. + + .. devices:: CPU CUDA + + .. properties:: TorchScript + + For more info see the + `Wikipedia Entry `_ + + This expects an input with values between 0 and ``quantization_channels - 1`` + and returns a signal scaled between -1 and 1. + + Args: + quantization_channels (int, optional): Number of channels. (Default: ``256``) + + Example + >>> waveform, sample_rate = torchaudio.load("test.wav", normalize=True) + >>> transform = torchaudio.transforms.MuLawDecoding(quantization_channels=512) + >>> mulawtrans = transform(waveform) + """ + __constants__ = ["quantization_channels"] + + def __init__(self, quantization_channels: int = 256) -> None: + super(MuLawDecoding, self).__init__() + self.quantization_channels = quantization_channels + + def forward(self, x_mu: Tensor) -> Tensor: + r""" + Args: + x_mu (Tensor): A mu-law encoded signal which needs to be decoded. + + Returns: + Tensor: The signal decoded. + """ + return F.mu_law_decoding(x_mu, self.quantization_channels) + + +class Resample(torch.nn.Module): + r"""Resample a signal from one frequency to another. A resampling method can be given. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Note: + If resampling on waveforms of higher precision than float32, there may be a small loss of precision + because the kernel is cached once as float32. If high precision resampling is important for your application, + the functional form will retain higher precision, but run slower because it does not cache the kernel. + Alternatively, you could rewrite a transform that caches a higher precision kernel. + + Args: + orig_freq (int, optional): The original frequency of the signal. (Default: ``16000``) + new_freq (int, optional): The desired frequency. (Default: ``16000``) + resampling_method (str, optional): The resampling method to use. + Options: [``sinc_interp_hann``, ``sinc_interp_kaiser``] (Default: ``"sinc_interp_hann"``) + lowpass_filter_width (int, optional): Controls the sharpness of the filter, more == sharper + but less efficient. (Default: ``6``) + rolloff (float, optional): The roll-off frequency of the filter, as a fraction of the Nyquist. + Lower values reduce anti-aliasing, but also reduce some of the highest frequencies. (Default: ``0.99``) + beta (float or None, optional): The shape parameter used for kaiser window. + dtype (torch.device, optional): + Determnines the precision that resampling kernel is pre-computed and cached. If not provided, + kernel is computed with ``torch.float64`` then cached as ``torch.float32``. + If you need higher precision, provide ``torch.float64``, and the pre-computed kernel is computed and + cached as ``torch.float64``. If you use resample with lower precision, then instead of providing this + providing this argument, please use ``Resample.to(dtype)``, so that the kernel generation is still + carried out on ``torch.float64``. + + Example + >>> waveform, sample_rate = torchaudio.load("test.wav", normalize=True) + >>> transform = transforms.Resample(sample_rate, sample_rate/10) + >>> waveform = transform(waveform) + """ + + def __init__( + self, + orig_freq: int = 16000, + new_freq: int = 16000, + resampling_method: str = "sinc_interp_hann", + lowpass_filter_width: int = 6, + rolloff: float = 0.99, + beta: Optional[float] = None, + *, + dtype: Optional[torch.dtype] = None, + ) -> None: + super().__init__() + + self.orig_freq = orig_freq + self.new_freq = new_freq + self.gcd = math.gcd(int(self.orig_freq), int(self.new_freq)) + self.resampling_method = resampling_method + self.lowpass_filter_width = lowpass_filter_width + self.rolloff = rolloff + self.beta = beta + + if self.orig_freq != self.new_freq: + kernel, self.width = _get_sinc_resample_kernel( + self.orig_freq, + self.new_freq, + self.gcd, + self.lowpass_filter_width, + self.rolloff, + self.resampling_method, + beta, + dtype=dtype, + ) + self.register_buffer("kernel", kernel) + + def forward(self, waveform: Tensor) -> Tensor: + r""" + Args: + waveform (Tensor): Tensor of audio of dimension (..., time). + + Returns: + Tensor: Output signal of dimension (..., time). + """ + if self.orig_freq == self.new_freq: + return waveform + return _apply_sinc_resample_kernel(waveform, self.orig_freq, self.new_freq, self.gcd, self.kernel, self.width) + + +class ComputeDeltas(torch.nn.Module): + r"""Compute delta coefficients of a tensor, usually a spectrogram. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + See `torchaudio.functional.compute_deltas` for more details. + + Args: + win_length (int, optional): The window length used for computing delta. (Default: ``5``) + mode (str, optional): Mode parameter passed to padding. (Default: ``"replicate"``) + """ + __constants__ = ["win_length"] + + def __init__(self, win_length: int = 5, mode: str = "replicate") -> None: + super(ComputeDeltas, self).__init__() + self.win_length = win_length + self.mode = mode + + def forward(self, specgram: Tensor) -> Tensor: + r""" + Args: + specgram (Tensor): Tensor of audio of dimension (..., freq, time). + + Returns: + Tensor: Tensor of deltas of dimension (..., freq, time). + """ + return F.compute_deltas(specgram, win_length=self.win_length, mode=self.mode) + + +class TimeStretch(torch.nn.Module): + r"""Stretch stft in time without modifying pitch for a given rate. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Proposed in *SpecAugment* :cite:`specaugment`. + + Args: + hop_length (int or None, optional): Length of hop between STFT windows. + (Default: ``n_fft // 2``, where ``n_fft == (n_freq - 1) * 2``) + n_freq (int, optional): number of filter banks from stft. (Default: ``201``) + fixed_rate (float or None, optional): rate to speed up or slow down by. + If None is provided, rate must be passed to the forward method. (Default: ``None``) + + .. note:: + + The expected input is raw, complex-valued spectrogram. + + Example + >>> spectrogram = torchaudio.transforms.Spectrogram(power=None) + >>> stretch = torchaudio.transforms.TimeStretch() + >>> + >>> original = spectrogram(waveform) + >>> stretched_1_2 = stretch(original, 1.2) + >>> stretched_0_9 = stretch(original, 0.9) + + .. image:: https://download.pytorch.org/torchaudio/doc-assets/specaugment_time_stretch.png + :width: 600 + :alt: The visualization of stretched spectrograms. + """ + __constants__ = ["fixed_rate"] + + def __init__(self, hop_length: Optional[int] = None, n_freq: int = 201, fixed_rate: Optional[float] = None) -> None: + super(TimeStretch, self).__init__() + + self.fixed_rate = fixed_rate + + n_fft = (n_freq - 1) * 2 + hop_length = hop_length if hop_length is not None else n_fft // 2 + self.register_buffer("phase_advance", torch.linspace(0, math.pi * hop_length, n_freq)[..., None]) + + def forward(self, complex_specgrams: Tensor, overriding_rate: Optional[float] = None) -> Tensor: + r""" + Args: + complex_specgrams (Tensor): + A tensor of dimension `(..., freq, num_frame)` with complex dtype. + overriding_rate (float or None, optional): speed up to apply to this batch. + If no rate is passed, use ``self.fixed_rate``. (Default: ``None``) + + Returns: + Tensor: + Stretched spectrogram. The resulting tensor is of the corresponding complex dtype + as the input spectrogram, and the number of frames is changed to ``ceil(num_frame / rate)``. + """ + if not torch.is_complex(complex_specgrams): + warnings.warn( + "The input to TimeStretch must be complex type. " + "Providing non-complex tensor produces invalid results.", + stacklevel=4, + ) + + if overriding_rate is None: + if self.fixed_rate is None: + raise ValueError("If no fixed_rate is specified, must pass a valid rate to the forward method.") + rate = self.fixed_rate + else: + rate = overriding_rate + return F.phase_vocoder(complex_specgrams, rate, self.phase_advance) + + +class Fade(torch.nn.Module): + r"""Add a fade in and/or fade out to an waveform. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Args: + fade_in_len (int, optional): Length of fade-in (time frames). (Default: ``0``) + fade_out_len (int, optional): Length of fade-out (time frames). (Default: ``0``) + fade_shape (str, optional): Shape of fade. Must be one of: "quarter_sine", + ``"half_sine"``, ``"linear"``, ``"logarithmic"``, ``"exponential"``. + (Default: ``"linear"``) + + Example + >>> waveform, sample_rate = torchaudio.load("test.wav", normalize=True) + >>> transform = transforms.Fade(fade_in_len=sample_rate, fade_out_len=2 * sample_rate, fade_shape="linear") + >>> faded_waveform = transform(waveform) + """ + + def __init__(self, fade_in_len: int = 0, fade_out_len: int = 0, fade_shape: str = "linear") -> None: + super(Fade, self).__init__() + self.fade_in_len = fade_in_len + self.fade_out_len = fade_out_len + self.fade_shape = fade_shape + + def forward(self, waveform: Tensor) -> Tensor: + r""" + Args: + waveform (Tensor): Tensor of audio of dimension `(..., time)`. + + Returns: + Tensor: Tensor of audio of dimension `(..., time)`. + """ + waveform_length = waveform.size()[-1] + device = waveform.device + return self._fade_in(waveform_length, device) * self._fade_out(waveform_length, device) * waveform + + def _fade_in(self, waveform_length: int, device: torch.device) -> Tensor: + fade = torch.linspace(0, 1, self.fade_in_len, device=device) + ones = torch.ones(waveform_length - self.fade_in_len, device=device) + + if self.fade_shape == "linear": + fade = fade + + if self.fade_shape == "exponential": + fade = torch.pow(2, (fade - 1)) * fade + + if self.fade_shape == "logarithmic": + fade = torch.log10(0.1 + fade) + 1 + + if self.fade_shape == "quarter_sine": + fade = torch.sin(fade * math.pi / 2) + + if self.fade_shape == "half_sine": + fade = torch.sin(fade * math.pi - math.pi / 2) / 2 + 0.5 + + return torch.cat((fade, ones)).clamp_(0, 1) + + def _fade_out(self, waveform_length: int, device: torch.device) -> Tensor: + fade = torch.linspace(0, 1, self.fade_out_len, device=device) + ones = torch.ones(waveform_length - self.fade_out_len, device=device) + + if self.fade_shape == "linear": + fade = -fade + 1 + + if self.fade_shape == "exponential": + fade = torch.pow(2, -fade) * (1 - fade) + + if self.fade_shape == "logarithmic": + fade = torch.log10(1.1 - fade) + 1 + + if self.fade_shape == "quarter_sine": + fade = torch.sin(fade * math.pi / 2 + math.pi / 2) + + if self.fade_shape == "half_sine": + fade = torch.sin(fade * math.pi + math.pi / 2) / 2 + 0.5 + + return torch.cat((ones, fade)).clamp_(0, 1) + + +class _AxisMasking(torch.nn.Module): + r"""Apply masking to a spectrogram. + + Args: + mask_param (int): Maximum possible length of the mask. + axis (int): What dimension the mask is applied on (assuming the tensor is 3D). + For frequency masking, axis = 1. + For time masking, axis = 2. + iid_masks (bool): Applies iid masks to each of the examples in the batch dimension. + This option is applicable only when the dimension of the input tensor is >= 3. + p (float, optional): maximum proportion of columns that can be masked. (Default: 1.0) + """ + __constants__ = ["mask_param", "axis", "iid_masks", "p"] + + def __init__(self, mask_param: int, axis: int, iid_masks: bool, p: float = 1.0) -> None: + super(_AxisMasking, self).__init__() + self.mask_param = mask_param + self.axis = axis + self.iid_masks = iid_masks + self.p = p + + def forward(self, specgram: Tensor, mask_value: float = 0.0) -> Tensor: + r""" + Args: + specgram (Tensor): Tensor of dimension `(..., freq, time)`. + mask_value (float): Value to assign to the masked columns. + + Returns: + Tensor: Masked spectrogram of dimensions `(..., freq, time)`. + """ + # if iid_masks flag marked and specgram has a batch dimension + # self.axis + specgram.dim() - 3 gives the time/frequency dimension (last two dimensions) + # for input tensor for which the dimension is not 3. + if self.iid_masks: + return F.mask_along_axis_iid( + specgram, self.mask_param, mask_value, self.axis + specgram.dim() - 3, p=self.p + ) + else: + return F.mask_along_axis(specgram, self.mask_param, mask_value, self.axis + specgram.dim() - 3, p=self.p) + + +class FrequencyMasking(_AxisMasking): + r"""Apply masking to a spectrogram in the frequency domain. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Proposed in *SpecAugment* :cite:`specaugment`. + + Args: + freq_mask_param (int): maximum possible length of the mask. + Indices uniformly sampled from [0, freq_mask_param). + iid_masks (bool, optional): whether to apply different masks to each + example/channel in the batch. (Default: ``False``) + This option is applicable only when the input tensor >= 3D. + + Example + >>> spectrogram = torchaudio.transforms.Spectrogram() + >>> masking = torchaudio.transforms.FrequencyMasking(freq_mask_param=80) + >>> + >>> original = spectrogram(waveform) + >>> masked = masking(original) + + .. image:: https://download.pytorch.org/torchaudio/doc-assets/specaugment_freq_masking1.png + :alt: The original spectrogram + + .. image:: https://download.pytorch.org/torchaudio/doc-assets/specaugment_freq_masking2.png + :alt: The spectrogram masked along frequency axis + """ + + def __init__(self, freq_mask_param: int, iid_masks: bool = False) -> None: + super(FrequencyMasking, self).__init__(freq_mask_param, 1, iid_masks) + + +class TimeMasking(_AxisMasking): + r"""Apply masking to a spectrogram in the time domain. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Proposed in *SpecAugment* :cite:`specaugment`. + + Args: + time_mask_param (int): maximum possible length of the mask. + Indices uniformly sampled from [0, time_mask_param). + iid_masks (bool, optional): whether to apply different masks to each + example/channel in the batch. (Default: ``False``) + This option is applicable only when the input tensor >= 3D. + p (float, optional): maximum proportion of time steps that can be masked. + Must be within range [0.0, 1.0]. (Default: 1.0) + + Example + >>> spectrogram = torchaudio.transforms.Spectrogram() + >>> masking = torchaudio.transforms.TimeMasking(time_mask_param=80) + >>> + >>> original = spectrogram(waveform) + >>> masked = masking(original) + + .. image:: https://download.pytorch.org/torchaudio/doc-assets/specaugment_time_masking1.png + :alt: The original spectrogram + + .. image:: https://download.pytorch.org/torchaudio/doc-assets/specaugment_time_masking2.png + :alt: The spectrogram masked along time axis + """ + + def __init__(self, time_mask_param: int, iid_masks: bool = False, p: float = 1.0) -> None: + if not 0.0 <= p <= 1.0: + raise ValueError(f"The value of p must be between 0.0 and 1.0 ({p} given).") + super(TimeMasking, self).__init__(time_mask_param, 2, iid_masks, p=p) + + +class SpecAugment(torch.nn.Module): + r"""Apply time and frequency masking to a spectrogram. + Args: + n_time_masks (int): Number of time masks. If its value is zero, no time masking will be applied. + time_mask_param (int): Maximum possible length of the time mask. + n_freq_masks (int): Number of frequency masks. If its value is zero, no frequency masking will be applied. + freq_mask_param (int): Maximum possible length of the frequency mask. + iid_masks (bool, optional): Applies iid masks to each of the examples in the batch dimension. + This option is applicable only when the input tensor is 4D. (Default: ``True``) + p (float, optional): maximum proportion of time steps that can be masked. + Must be within range [0.0, 1.0]. (Default: 1.0) + zero_masking (bool, optional): If ``True``, use 0 as the mask value, + else use mean of the input tensor. (Default: ``False``) + """ + __constants__ = [ + "n_time_masks", + "time_mask_param", + "n_freq_masks", + "freq_mask_param", + "iid_masks", + "p", + "zero_masking", + ] + + def __init__( + self, + n_time_masks: int, + time_mask_param: int, + n_freq_masks: int, + freq_mask_param: int, + iid_masks: bool = True, + p: float = 1.0, + zero_masking: bool = False, + ) -> None: + super(SpecAugment, self).__init__() + self.n_time_masks = n_time_masks + self.time_mask_param = time_mask_param + self.n_freq_masks = n_freq_masks + self.freq_mask_param = freq_mask_param + self.iid_masks = iid_masks + self.p = p + self.zero_masking = zero_masking + + def forward(self, specgram: Tensor) -> Tensor: + r""" + Args: + specgram (Tensor): Tensor of shape `(..., freq, time)`. + Returns: + Tensor: Masked spectrogram of shape `(..., freq, time)`. + """ + if self.zero_masking: + mask_value = 0.0 + else: + mask_value = specgram.mean() + time_dim = specgram.dim() - 1 + freq_dim = time_dim - 1 + + if specgram.dim() > 2 and self.iid_masks is True: + for _ in range(self.n_time_masks): + specgram = F.mask_along_axis_iid(specgram, self.time_mask_param, mask_value, time_dim, p=self.p) + for _ in range(self.n_freq_masks): + specgram = F.mask_along_axis_iid(specgram, self.freq_mask_param, mask_value, freq_dim, p=self.p) + else: + for _ in range(self.n_time_masks): + specgram = F.mask_along_axis(specgram, self.time_mask_param, mask_value, time_dim, p=self.p) + for _ in range(self.n_freq_masks): + specgram = F.mask_along_axis(specgram, self.freq_mask_param, mask_value, freq_dim, p=self.p) + + return specgram + + +class Loudness(torch.nn.Module): + r"""Measure audio loudness according to the ITU-R BS.1770-4 recommendation. + + .. devices:: CPU CUDA + + .. properties:: TorchScript + + Args: + sample_rate (int): Sample rate of audio signal. + + Example + >>> waveform, sample_rate = torchaudio.load("test.wav", normalize=True) + >>> transform = transforms.Loudness(sample_rate) + >>> loudness = transform(waveform) + + Reference: + - https://www.itu.int/rec/R-REC-BS.1770-4-201510-I/en + """ + __constants__ = ["sample_rate"] + + def __init__(self, sample_rate: int): + super(Loudness, self).__init__() + self.sample_rate = sample_rate + + def forward(self, wavefrom: Tensor): + r""" + Args: + waveform(torch.Tensor): audio waveform of dimension `(..., channels, time)` + + Returns: + Tensor: loudness estimates (LKFS) + """ + return F.loudness(wavefrom, self.sample_rate) + + +class Vol(torch.nn.Module): + r"""Adjust volume of waveform. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Args: + gain (float): Interpreted according to the given gain_type: + If ``gain_type`` = ``amplitude``, ``gain`` is a positive amplitude ratio. + If ``gain_type`` = ``power``, ``gain`` is a power (voltage squared). + If ``gain_type`` = ``db``, ``gain`` is in decibels. + gain_type (str, optional): Type of gain. One of: ``amplitude``, ``power``, ``db`` (Default: ``amplitude``) + + Example + >>> waveform, sample_rate = torchaudio.load("test.wav", normalize=True) + >>> transform = transforms.Vol(gain=0.5, gain_type="amplitude") + >>> quieter_waveform = transform(waveform) + """ + + def __init__(self, gain: float, gain_type: str = "amplitude"): + super(Vol, self).__init__() + self.gain = gain + self.gain_type = gain_type + + if gain_type in ["amplitude", "power"] and gain < 0: + raise ValueError("If gain_type = amplitude or power, gain must be positive.") + + def forward(self, waveform: Tensor) -> Tensor: + r""" + Args: + waveform (Tensor): Tensor of audio of dimension `(..., time)`. + + Returns: + Tensor: Tensor of audio of dimension `(..., time)`. + """ + if self.gain_type == "amplitude": + waveform = waveform * self.gain + + if self.gain_type == "db": + waveform = F.gain(waveform, self.gain) + + if self.gain_type == "power": + waveform = F.gain(waveform, 10 * math.log10(self.gain)) + + return torch.clamp(waveform, -1, 1) + + +class SlidingWindowCmn(torch.nn.Module): + r""" + Apply sliding-window cepstral mean (and optionally variance) normalization per utterance. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Args: + cmn_window (int, optional): Window in frames for running average CMN computation (int, default = 600) + min_cmn_window (int, optional): Minimum CMN window used at start of decoding (adds latency only at start). + Only applicable if center == false, ignored if center==true (int, default = 100) + center (bool, optional): If true, use a window centered on the current frame + (to the extent possible, modulo end effects). If false, window is to the left. (bool, default = false) + norm_vars (bool, optional): If true, normalize variance to one. (bool, default = false) + + Example + >>> waveform, sample_rate = torchaudio.load("test.wav", normalize=True) + >>> transform = transforms.SlidingWindowCmn(cmn_window=1000) + >>> cmn_waveform = transform(waveform) + """ + + def __init__( + self, cmn_window: int = 600, min_cmn_window: int = 100, center: bool = False, norm_vars: bool = False + ) -> None: + super().__init__() + self.cmn_window = cmn_window + self.min_cmn_window = min_cmn_window + self.center = center + self.norm_vars = norm_vars + + def forward(self, specgram: Tensor) -> Tensor: + r""" + Args: + specgram (Tensor): Tensor of spectrogram of dimension `(..., time, freq)`. + + Returns: + Tensor: Tensor of spectrogram of dimension `(..., time, freq)`. + """ + cmn_specgram = F.sliding_window_cmn(specgram, self.cmn_window, self.min_cmn_window, self.center, self.norm_vars) + return cmn_specgram + + +class Vad(torch.nn.Module): + r"""Voice Activity Detector. Similar to SoX implementation. + + .. devices:: CPU CUDA + + .. properties:: TorchScript + + Attempts to trim silence and quiet background sounds from the ends of recordings of speech. + The algorithm currently uses a simple cepstral power measurement to detect voice, + so may be fooled by other things, especially music. + + The effect can trim only from the front of the audio, + so in order to trim from the back, the reverse effect must also be used. + + Args: + sample_rate (int): Sample rate of audio signal. + trigger_level (float, optional): The measurement level used to trigger activity detection. + This may need to be changed depending on the noise level, signal level, + and other characteristics of the input audio. (Default: 7.0) + trigger_time (float, optional): The time constant (in seconds) + used to help ignore short bursts of sound. (Default: 0.25) + search_time (float, optional): The amount of audio (in seconds) + to search for quieter/shorter bursts of audio to include prior + to the detected trigger point. (Default: 1.0) + allowed_gap (float, optional): The allowed gap (in seconds) between + quiteter/shorter bursts of audio to include prior + to the detected trigger point. (Default: 0.25) + pre_trigger_time (float, optional): The amount of audio (in seconds) to preserve + before the trigger point and any found quieter/shorter bursts. (Default: 0.0) + boot_time (float, optional) The algorithm (internally) uses adaptive noise + estimation/reduction in order to detect the start of the wanted audio. + This option sets the time for the initial noise estimate. (Default: 0.35) + noise_up_time (float, optional) Time constant used by the adaptive noise estimator + for when the noise level is increasing. (Default: 0.1) + noise_down_time (float, optional) Time constant used by the adaptive noise estimator + for when the noise level is decreasing. (Default: 0.01) + noise_reduction_amount (float, optional) Amount of noise reduction to use in + the detection algorithm (e.g. 0, 0.5, ...). (Default: 1.35) + measure_freq (float, optional) Frequency of the algorithmโ€™s + processing/measurements. (Default: 20.0) + measure_duration: (float or None, optional) Measurement duration. + (Default: Twice the measurement period; i.e. with overlap.) + measure_smooth_time (float, optional) Time constant used to smooth + spectral measurements. (Default: 0.4) + hp_filter_freq (float, optional) "Brick-wall" frequency of high-pass filter applied + at the input to the detector algorithm. (Default: 50.0) + lp_filter_freq (float, optional) "Brick-wall" frequency of low-pass filter applied + at the input to the detector algorithm. (Default: 6000.0) + hp_lifter_freq (float, optional) "Brick-wall" frequency of high-pass lifter used + in the detector algorithm. (Default: 150.0) + lp_lifter_freq (float, optional) "Brick-wall" frequency of low-pass lifter used + in the detector algorithm. (Default: 2000.0) + + Example + >>> waveform, sample_rate = torchaudio.load("test.wav", normalize=True) + >>> waveform_reversed, sample_rate = apply_effects_tensor(waveform, sample_rate, [["reverse"]]) + >>> transform = transforms.Vad(sample_rate=sample_rate, trigger_level=7.5) + >>> waveform_reversed_front_trim = transform(waveform_reversed) + >>> waveform_end_trim, sample_rate = apply_effects_tensor( + >>> waveform_reversed_front_trim, sample_rate, [["reverse"]] + >>> ) + + Reference: + - http://sox.sourceforge.net/sox.html + """ + + def __init__( + self, + sample_rate: int, + trigger_level: float = 7.0, + trigger_time: float = 0.25, + search_time: float = 1.0, + allowed_gap: float = 0.25, + pre_trigger_time: float = 0.0, + boot_time: float = 0.35, + noise_up_time: float = 0.1, + noise_down_time: float = 0.01, + noise_reduction_amount: float = 1.35, + measure_freq: float = 20.0, + measure_duration: Optional[float] = None, + measure_smooth_time: float = 0.4, + hp_filter_freq: float = 50.0, + lp_filter_freq: float = 6000.0, + hp_lifter_freq: float = 150.0, + lp_lifter_freq: float = 2000.0, + ) -> None: + super().__init__() + + self.sample_rate = sample_rate + self.trigger_level = trigger_level + self.trigger_time = trigger_time + self.search_time = search_time + self.allowed_gap = allowed_gap + self.pre_trigger_time = pre_trigger_time + self.boot_time = boot_time + self.noise_up_time = noise_up_time + self.noise_down_time = noise_down_time + self.noise_reduction_amount = noise_reduction_amount + self.measure_freq = measure_freq + self.measure_duration = measure_duration + self.measure_smooth_time = measure_smooth_time + self.hp_filter_freq = hp_filter_freq + self.lp_filter_freq = lp_filter_freq + self.hp_lifter_freq = hp_lifter_freq + self.lp_lifter_freq = lp_lifter_freq + + def forward(self, waveform: Tensor) -> Tensor: + r""" + Args: + waveform (Tensor): Tensor of audio of dimension `(channels, time)` or `(time)` + Tensor of shape `(channels, time)` is treated as a multi-channel recording + of the same event and the resulting output will be trimmed to the earliest + voice activity in any channel. + """ + return F.vad( + waveform=waveform, + sample_rate=self.sample_rate, + trigger_level=self.trigger_level, + trigger_time=self.trigger_time, + search_time=self.search_time, + allowed_gap=self.allowed_gap, + pre_trigger_time=self.pre_trigger_time, + boot_time=self.boot_time, + noise_up_time=self.noise_up_time, + noise_down_time=self.noise_down_time, + noise_reduction_amount=self.noise_reduction_amount, + measure_freq=self.measure_freq, + measure_duration=self.measure_duration, + measure_smooth_time=self.measure_smooth_time, + hp_filter_freq=self.hp_filter_freq, + lp_filter_freq=self.lp_filter_freq, + hp_lifter_freq=self.hp_lifter_freq, + lp_lifter_freq=self.lp_lifter_freq, + ) + + +class SpectralCentroid(torch.nn.Module): + r"""Compute the spectral centroid for each channel along the time axis. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + The spectral centroid is defined as the weighted average of the + frequency values, weighted by their magnitude. + + Args: + sample_rate (int): Sample rate of audio signal. + n_fft (int, optional): Size of FFT, creates ``n_fft // 2 + 1`` bins. (Default: ``400``) + win_length (int or None, optional): Window size. (Default: ``n_fft``) + hop_length (int or None, optional): Length of hop between STFT windows. (Default: ``win_length // 2``) + pad (int, optional): Two sided padding of signal. (Default: ``0``) + window_fn (Callable[..., Tensor], optional): A function to create a window tensor + that is applied/multiplied to each frame/window. (Default: ``torch.hann_window``) + wkwargs (dict or None, optional): Arguments for window function. (Default: ``None``) + + Example + >>> waveform, sample_rate = torchaudio.load("test.wav", normalize=True) + >>> transform = transforms.SpectralCentroid(sample_rate) + >>> spectral_centroid = transform(waveform) # (channel, time) + """ + __constants__ = ["sample_rate", "n_fft", "win_length", "hop_length", "pad"] + + def __init__( + self, + sample_rate: int, + n_fft: int = 400, + win_length: Optional[int] = None, + hop_length: Optional[int] = None, + pad: int = 0, + window_fn: Callable[..., Tensor] = torch.hann_window, + wkwargs: Optional[dict] = None, + ) -> None: + super(SpectralCentroid, self).__init__() + self.sample_rate = sample_rate + self.n_fft = n_fft + self.win_length = win_length if win_length is not None else n_fft + self.hop_length = hop_length if hop_length is not None else self.win_length // 2 + window = window_fn(self.win_length) if wkwargs is None else window_fn(self.win_length, **wkwargs) + self.register_buffer("window", window) + self.pad = pad + + def forward(self, waveform: Tensor) -> Tensor: + r""" + Args: + waveform (Tensor): Tensor of audio of dimension `(..., time)`. + + Returns: + Tensor: Spectral Centroid of size `(..., time)`. + """ + + return F.spectral_centroid( + waveform, self.sample_rate, self.pad, self.window, self.n_fft, self.hop_length, self.win_length + ) + + +class PitchShift(LazyModuleMixin, torch.nn.Module): + r"""Shift the pitch of a waveform by ``n_steps`` steps. + + .. devices:: CPU CUDA + + .. properties:: TorchScript + + Args: + waveform (Tensor): The input waveform of shape `(..., time)`. + sample_rate (int): Sample rate of `waveform`. + n_steps (int): The (fractional) steps to shift `waveform`. + bins_per_octave (int, optional): The number of steps per octave (Default : ``12``). + n_fft (int, optional): Size of FFT, creates ``n_fft // 2 + 1`` bins (Default: ``512``). + win_length (int or None, optional): Window size. If None, then ``n_fft`` is used. (Default: ``None``). + hop_length (int or None, optional): Length of hop between STFT windows. If None, then ``win_length // 4`` + is used (Default: ``None``). + window (Tensor or None, optional): Window tensor that is applied/multiplied to each frame/window. + If None, then ``torch.hann_window(win_length)`` is used (Default: ``None``). + + Example + >>> waveform, sample_rate = torchaudio.load("test.wav", normalize=True) + >>> transform = transforms.PitchShift(sample_rate, 4) + >>> waveform_shift = transform(waveform) # (channel, time) + """ + __constants__ = ["sample_rate", "n_steps", "bins_per_octave", "n_fft", "win_length", "hop_length"] + + kernel: UninitializedParameter + width: int + + def __init__( + self, + sample_rate: int, + n_steps: int, + bins_per_octave: int = 12, + n_fft: int = 512, + win_length: Optional[int] = None, + hop_length: Optional[int] = None, + window_fn: Callable[..., Tensor] = torch.hann_window, + wkwargs: Optional[dict] = None, + ) -> None: + super().__init__() + self.n_steps = n_steps + self.bins_per_octave = bins_per_octave + self.sample_rate = sample_rate + self.n_fft = n_fft + self.win_length = win_length if win_length is not None else n_fft + self.hop_length = hop_length if hop_length is not None else self.win_length // 4 + window = window_fn(self.win_length) if wkwargs is None else window_fn(self.win_length, **wkwargs) + self.register_buffer("window", window) + rate = 2.0 ** (-float(n_steps) / bins_per_octave) + self.orig_freq = int(sample_rate / rate) + self.gcd = math.gcd(int(self.orig_freq), int(sample_rate)) + + if self.orig_freq != sample_rate: + self.width = -1 + self.kernel = UninitializedParameter(device=None, dtype=None) + + def initialize_parameters(self, input): + if self.has_uninitialized_params(): + if self.orig_freq != self.sample_rate: + with torch.no_grad(): + kernel, self.width = _get_sinc_resample_kernel( + self.orig_freq, + self.sample_rate, + self.gcd, + dtype=input.dtype, + device=input.device, + ) + self.kernel.materialize(kernel.shape) + self.kernel.copy_(kernel) + + def forward(self, waveform: Tensor) -> Tensor: + r""" + Args: + waveform (Tensor): Tensor of audio of dimension `(..., time)`. + + Returns: + Tensor: The pitch-shifted audio of shape `(..., time)`. + """ + shape = waveform.size() + + waveform_stretch = _stretch_waveform( + waveform, + self.n_steps, + self.bins_per_octave, + self.n_fft, + self.win_length, + self.hop_length, + self.window, + ) + + if self.orig_freq != self.sample_rate: + waveform_shift = _apply_sinc_resample_kernel( + waveform_stretch, + self.orig_freq, + self.sample_rate, + self.gcd, + self.kernel, + self.width, + ) + else: + waveform_shift = waveform_stretch + + return _fix_waveform_shape( + waveform_shift, + shape, + ) + + +class RNNTLoss(torch.nn.Module): + """Compute the RNN Transducer loss from *Sequence Transduction with Recurrent Neural Networks* + :cite:`graves2012sequence`. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + The RNN Transducer loss extends the CTC loss by defining a distribution over output + sequences of all lengths, and by jointly modelling both input-output and output-output + dependencies. + + Args: + blank (int, optional): blank label (Default: ``-1``) + clamp (float, optional): clamp for gradients (Default: ``-1``) + reduction (string, optional): Specifies the reduction to apply to the output: + ``"none"`` | ``"mean"`` | ``"sum"``. (Default: ``"mean"``) + fused_log_softmax (bool): set to False if calling log_softmax outside of loss (Default: ``True``) + + Example + >>> # Hypothetical values + >>> logits = torch.tensor([[[[0.1, 0.6, 0.1, 0.1, 0.1], + >>> [0.1, 0.1, 0.6, 0.1, 0.1], + >>> [0.1, 0.1, 0.2, 0.8, 0.1]], + >>> [[0.1, 0.6, 0.1, 0.1, 0.1], + >>> [0.1, 0.1, 0.2, 0.1, 0.1], + >>> [0.7, 0.1, 0.2, 0.1, 0.1]]]], + >>> dtype=torch.float32, + >>> requires_grad=True) + >>> targets = torch.tensor([[1, 2]], dtype=torch.int) + >>> logit_lengths = torch.tensor([2], dtype=torch.int) + >>> target_lengths = torch.tensor([2], dtype=torch.int) + >>> transform = transforms.RNNTLoss(blank=0) + >>> loss = transform(logits, targets, logit_lengths, target_lengths) + >>> loss.backward() + """ + + def __init__( + self, + blank: int = -1, + clamp: float = -1.0, + reduction: str = "mean", + fused_log_softmax: bool = True, + ): + super().__init__() + self.blank = blank + self.clamp = clamp + self.reduction = reduction + self.fused_log_softmax = fused_log_softmax + + def forward( + self, + logits: Tensor, + targets: Tensor, + logit_lengths: Tensor, + target_lengths: Tensor, + ): + """ + Args: + logits (Tensor): Tensor of dimension `(batch, max seq length, max target length + 1, class)` + containing output from joiner + targets (Tensor): Tensor of dimension `(batch, max target length)` containing targets with zero padded + logit_lengths (Tensor): Tensor of dimension `(batch)` containing lengths of each sequence from encoder + target_lengths (Tensor): Tensor of dimension `(batch)` containing lengths of targets for each sequence + Returns: + Tensor: Loss with the reduction option applied. If ``reduction`` is ``"none"``, then size (batch), + otherwise scalar. + """ + return F.rnnt_loss( + logits, + targets, + logit_lengths, + target_lengths, + self.blank, + self.clamp, + self.reduction, + self.fused_log_softmax, + ) + + +class Convolve(torch.nn.Module): + r""" + Convolves inputs along their last dimension using the direct method. + Note that, in contrast to :class:`torch.nn.Conv1d`, which actually applies the valid cross-correlation + operator, this module applies the true `convolution`_ operator. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Args: + mode (str, optional): Must be one of ("full", "valid", "same"). + + * "full": Returns the full convolution result, with shape `(..., N + M - 1)`, where + `N` and `M` are the trailing dimensions of the two inputs. (Default) + * "valid": Returns the segment of the full convolution result corresponding to where + the two inputs overlap completely, with shape `(..., max(N, M) - min(N, M) + 1)`. + * "same": Returns the center segment of the full convolution result, with shape `(..., N)`. + + .. _convolution: + https://en.wikipedia.org/wiki/Convolution + """ + + def __init__(self, mode: str = "full") -> None: + _check_convolve_mode(mode) + + super().__init__() + self.mode = mode + + def forward(self, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + r""" + Args: + x (torch.Tensor): First convolution operand, with shape `(..., N)`. + y (torch.Tensor): Second convolution operand, with shape `(..., M)` + (leading dimensions must be broadcast-able with those of ``x``). + + Returns: + torch.Tensor: Result of convolving ``x`` and ``y``, with shape `(..., L)`, where + the leading dimensions match those of ``x`` and `L` is dictated by ``mode``. + """ + return F.convolve(x, y, mode=self.mode) + + +class FFTConvolve(torch.nn.Module): + r""" + Convolves inputs along their last dimension using FFT. For inputs with large last dimensions, this module + is generally much faster than :class:`Convolve`. + Note that, in contrast to :class:`torch.nn.Conv1d`, which actually applies the valid cross-correlation + operator, this module applies the true `convolution`_ operator. + Also note that this module can only output float tensors (int tensor inputs will be cast to float). + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Args: + mode (str, optional): Must be one of ("full", "valid", "same"). + + * "full": Returns the full convolution result, with shape `(..., N + M - 1)`, where + `N` and `M` are the trailing dimensions of the two inputs. (Default) + * "valid": Returns the segment of the full convolution result corresponding to where + the two inputs overlap completely, with shape `(..., max(N, M) - min(N, M) + 1)`. + * "same": Returns the center segment of the full convolution result, with shape `(..., N)`. + + .. _convolution: + https://en.wikipedia.org/wiki/Convolution + """ + + def __init__(self, mode: str = "full") -> None: + _check_convolve_mode(mode) + + super().__init__() + self.mode = mode + + def forward(self, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: + r""" + Args: + x (torch.Tensor): First convolution operand, with shape `(..., N)`. + y (torch.Tensor): Second convolution operand, with shape `(..., M)` + (leading dimensions must be broadcast-able with those of ``x``). + + Returns: + torch.Tensor: Result of convolving ``x`` and ``y``, with shape `(..., L)`, where + the leading dimensions match those of ``x`` and `L` is dictated by ``mode``. + """ + return F.fftconvolve(x, y, mode=self.mode) + + +def _source_target_sample_rate(orig_freq: int, speed: float) -> Tuple[int, int]: + source_sample_rate = int(speed * orig_freq) + target_sample_rate = int(orig_freq) + gcd = math.gcd(source_sample_rate, target_sample_rate) + return source_sample_rate // gcd, target_sample_rate // gcd + + +class Speed(torch.nn.Module): + r"""Adjusts waveform speed. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Args: + orig_freq (int): Original frequency of the signals in ``waveform``. + factor (float): Factor by which to adjust speed of input. Values greater than 1.0 + compress ``waveform`` in time, whereas values less than 1.0 stretch ``waveform`` in time. + """ + + def __init__(self, orig_freq, factor) -> None: + super().__init__() + + self.orig_freq = orig_freq + self.factor = factor + + self.source_sample_rate, self.target_sample_rate = _source_target_sample_rate(orig_freq, factor) + self.resampler = Resample(orig_freq=self.source_sample_rate, new_freq=self.target_sample_rate) + + def forward(self, waveform, lengths: Optional[torch.Tensor] = None) -> Tuple[torch.Tensor, Optional[torch.Tensor]]: + r""" + Args: + waveform (torch.Tensor): Input signals, with shape `(..., time)`. + lengths (torch.Tensor or None, optional): Valid lengths of signals in ``waveform``, with shape `(...)`. + If ``None``, all elements in ``waveform`` are treated as valid. (Default: ``None``) + + Returns: + (torch.Tensor, torch.Tensor or None): + torch.Tensor + Speed-adjusted waveform, with shape `(..., new_time).` + torch.Tensor or None + If ``lengths`` is not ``None``, valid lengths of signals in speed-adjusted waveform, + with shape `(...)`; otherwise, ``None``. + """ + + if lengths is None: + out_lengths = None + else: + out_lengths = torch.ceil(lengths * self.target_sample_rate / self.source_sample_rate).to(lengths.dtype) + + return self.resampler(waveform), out_lengths + + +class SpeedPerturbation(torch.nn.Module): + r"""Applies the speed perturbation augmentation introduced in + *Audio augmentation for speech recognition* :cite:`ko15_interspeech`. For a given input, + the module samples a speed-up factor from ``factors`` uniformly at random and adjusts + the speed of the input by that factor. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Args: + orig_freq (int): Original frequency of the signals in ``waveform``. + factors (Sequence[float]): Factors by which to adjust speed of input. Values greater than 1.0 + compress ``waveform`` in time, whereas values less than 1.0 stretch ``waveform`` in time. + + Example + >>> speed_perturb = SpeedPerturbation(16000, [0.9, 1.1, 1.0, 1.0, 1.0]) + >>> # waveform speed will be adjusted by factor 0.9 with 20% probability, + >>> # 1.1 with 20% probability, and 1.0 (i.e. kept the same) with 60% probability. + >>> speed_perturbed_waveform = speed_perturb(waveform, lengths) + """ + + def __init__(self, orig_freq: int, factors: Sequence[float]) -> None: + super().__init__() + + self.speeders = torch.nn.ModuleList([Speed(orig_freq=orig_freq, factor=factor) for factor in factors]) + + def forward( + self, waveform: torch.Tensor, lengths: Optional[torch.Tensor] = None + ) -> Tuple[torch.Tensor, Optional[torch.Tensor]]: + r""" + Args: + waveform (torch.Tensor): Input signals, with shape `(..., time)`. + lengths (torch.Tensor or None, optional): Valid lengths of signals in ``waveform``, with shape `(...)`. + If ``None``, all elements in ``waveform`` are treated as valid. (Default: ``None``) + + Returns: + (torch.Tensor, torch.Tensor or None): + torch.Tensor + Speed-adjusted waveform, with shape `(..., new_time).` + torch.Tensor or None + If ``lengths`` is not ``None``, valid lengths of signals in speed-adjusted waveform, + with shape `(...)`; otherwise, ``None``. + """ + + idx = int(torch.randint(len(self.speeders), ())) + # NOTE: we do this because TorchScript doesn't allow for + # indexing ModuleList instances with non-literals. + for speeder_idx, speeder in enumerate(self.speeders): + if idx == speeder_idx: + return speeder(waveform, lengths) + raise RuntimeError("Speeder not found; execution should have never reached here.") + + +class AddNoise(torch.nn.Module): + r"""Scales and adds noise to waveform per signal-to-noise ratio. + See :meth:`torchaudio.functional.add_noise` for more details. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + """ + + def forward( + self, waveform: torch.Tensor, noise: torch.Tensor, snr: torch.Tensor, lengths: Optional[torch.Tensor] = None + ) -> torch.Tensor: + r""" + Args: + waveform (torch.Tensor): Input waveform, with shape `(..., L)`. + noise (torch.Tensor): Noise, with shape `(..., L)` (same shape as ``waveform``). + snr (torch.Tensor): Signal-to-noise ratios in dB, with shape `(...,)`. + lengths (torch.Tensor or None, optional): Valid lengths of signals in ``waveform`` and ``noise``, + with shape `(...,)` (leading dimensions must match those of ``waveform``). If ``None``, all + elements in ``waveform`` and ``noise`` are treated as valid. (Default: ``None``) + + Returns: + torch.Tensor: Result of scaling and adding ``noise`` to ``waveform``, with shape `(..., L)` + (same shape as ``waveform``). + """ + return F.add_noise(waveform, noise, snr, lengths) + + +class Preemphasis(torch.nn.Module): + r"""Pre-emphasizes a waveform along its last dimension. + See :meth:`torchaudio.functional.preemphasis` for more details. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Args: + coeff (float, optional): Pre-emphasis coefficient. Typically between 0.0 and 1.0. + (Default: 0.97) + """ + + def __init__(self, coeff: float = 0.97) -> None: + super().__init__() + self.coeff = coeff + + def forward(self, waveform: torch.Tensor) -> torch.Tensor: + r""" + Args: + waveform (torch.Tensor): Waveform, with shape `(..., N)`. + + Returns: + torch.Tensor: Pre-emphasized waveform, with shape `(..., N)`. + """ + return F.preemphasis(waveform, coeff=self.coeff) + + +class Deemphasis(torch.nn.Module): + r"""De-emphasizes a waveform along its last dimension. + See :meth:`torchaudio.functional.deemphasis` for more details. + + .. devices:: CPU CUDA + + .. properties:: Autograd TorchScript + + Args: + coeff (float, optional): De-emphasis coefficient. Typically between 0.0 and 1.0. + (Default: 0.97) + """ + + def __init__(self, coeff: float = 0.97) -> None: + super().__init__() + self.coeff = coeff + + def forward(self, waveform: torch.Tensor) -> torch.Tensor: + r""" + Args: + waveform (torch.Tensor): Waveform, with shape `(..., N)`. + + Returns: + torch.Tensor: De-emphasized waveform, with shape `(..., N)`. + """ + return F.deemphasis(waveform, coeff=self.coeff)