xmodaler.utils¶
- xmodaler.utils.colormap.colormap(rgb=False, maximum=255)[source]¶
- Parameters:
rgb (bool) – whether to return RGB colors or BGR colors.
maximum (int) – either 255 or 1
- Returns:
a float32 array of Nx3 colors, in range [0, 255] or [0, 1]
- Return type:
ndarray
- xmodaler.utils.colormap.random_color(rgb=False, maximum=255)[source]¶
- Parameters:
rgb (bool) – whether to return RGB colors or BGR colors.
maximum (int) – either 255 or 1
- Returns:
a vector of 3 numbers
- Return type:
ndarray
- xmodaler.utils.comm.all_gather(data, group=None)[source]¶
Run all_gather on arbitrary picklable data (not necessarily tensors).
- Parameters:
data – any picklable object
group – a torch process group. By default, will use a group which contains all ranks on gloo backend.
- Returns:
list of data gathered from each rank
- Return type:
list[data]
- xmodaler.utils.comm.gather(data, dst=0, group=None)[source]¶
Run gather on arbitrary picklable data (not necessarily tensors).
- Parameters:
data – any picklable object
dst (int) – destination rank
group – a torch process group. By default, will use a group which contains all ranks on gloo backend.
- Returns:
- on dst, a list of data gathered from each rank. Otherwise,
an empty list.
- Return type:
list[data]
- xmodaler.utils.distributed.all_gather_list(data)[source]¶
Gathers arbitrary data from all nodes into a list.
. autofunction:: xmodaler.utils.comm.any_broadcast
- xmodaler.utils.comm.get_local_rank() int [source]¶
- Returns:
The rank of the current process within the local (per-machine) process group.
- xmodaler.utils.comm.get_local_size() int [source]¶
- Returns:
The size of the per-machine process group, i.e. the number of processes per machine.
- xmodaler.utils.comm.reduce_dict(input_dict, average=True)[source]¶
Reduce the values in the dictionary from all processes so that process with rank 0 has the reduced results.
- Parameters:
input_dict (dict) – inputs to be reduced. All the values must be scalar CUDA Tensor.
average (bool) – whether to do average or sum
- Returns:
a dict with the same keys as input_dict, after reduction.
- Returns:
- a random number that is the same across all workers.
If workers need a shared RNG, they can use this shared seed to create one.
- Return type:
int
All workers must call this function, otherwise it will deadlock.
- xmodaler.utils.comm.synchronize()[source]¶
Helper function to synchronize (barrier) among all processes when using distributed training
- xmodaler.utils.env.seed_all_rng(seed=None)[source]¶
Set the random seed for the RNG in torch, numpy and python.
- Parameters:
seed (int) – if None, will use a strong random seed.
- xmodaler.utils.env.setup_environment()[source]¶
Perform environment setup work. The default setup is a no-op, but this function allows the user to specify a Python source file or a module in the $DETECTRON2_ENV_MODULE environment variable, that performs custom setup work that may be necessary to their computing environment.
- xmodaler.utils.env.setup_custom_environment(custom_module)[source]¶
Load custom environment setup by importing a Python source file or a module, and run the setup function.
- xmodaler.utils.events.get_event_storage()[source]¶
- Returns:
The
EventStorage
object that’s currently being used. Throws an error if noEventStorage
is currently enabled.
- class xmodaler.utils.events.JSONWriter(json_file, window_size=20)[source]¶
Bases:
EventWriter
Write scalars to a json file.
It saves scalars as one json per line (instead of a big json) for easy parsing.
Examples parsing such a json file:
$ cat metrics.json | jq -s '.[0:2]' [ { "data_time": 0.008433341979980469, "iteration": 19, "loss": 1.9228371381759644, "loss_box_reg": 0.050025828182697296, "loss_classifier": 0.5316952466964722, "loss_mask": 0.7236229181289673, "loss_rpn_box": 0.0856662318110466, "loss_rpn_cls": 0.48198649287223816, "lr": 0.007173333333333333, "time": 0.25401854515075684 }, { "data_time": 0.007216215133666992, "iteration": 39, "loss": 1.282649278640747, "loss_box_reg": 0.06222952902317047, "loss_classifier": 0.30682939291000366, "loss_mask": 0.6970193982124329, "loss_rpn_box": 0.038663312792778015, "loss_rpn_cls": 0.1471673548221588, "lr": 0.007706666666666667, "time": 0.2490077018737793 } ] $ cat metrics.json | jq '.loss_mask' 0.7126231789588928 0.689423680305481 0.6776131987571716 ...
- class xmodaler.utils.events.TensorboardXWriter(log_dir: str, window_size: int = 20, **kwargs)[source]¶
Bases:
EventWriter
Write all scalars to a tensorboard file.
- class xmodaler.utils.events.CommonMetricPrinter(max_iter: Optional[int] = None)[source]¶
Bases:
EventWriter
Print common metrics to the terminal, including iteration time, ETA, memory, all losses, and the learning rate. It also applies smoothing using a window of 20 elements.
It’s meant to print common metrics in common ways. To print something in more customized ways, please implement a similar printer by yourself.
- class xmodaler.utils.events.EventStorage(start_iter=0)[source]¶
Bases:
object
The user-facing class that provides metric storage functionalities.
In the future we may add support for storing / logging other types of data if needed.
- clear_histograms()[source]¶
Delete all the stored histograms for visualization. This should be called after histograms are written to tensorboard.
- clear_images()[source]¶
Delete all the stored images for visualization. This should be called after images are written to tensorboard.
- histories()[source]¶
- Returns:
the HistoryBuffer for all scalars
- Return type:
dict[name -> HistoryBuffer]
- property iter¶
Returns: int: The current iteration number. When used together with a trainer,
this is ensured to be the same as trainer.iter.
- property iteration¶
- latest()[source]¶
- Returns:
- mapping from the name of each scalar to the most
recent value and the iteration number its added.
- Return type:
dict[str -> (float, int)]
- latest_with_smoothing_hint(window_size=20)[source]¶
Similar to
latest()
, but the returned values are either the un-smoothed original latest value, or a median of the given window_size, depend on whether the smoothing_hint is True.This provides a default behavior that other writers can use.
- name_scope(name)[source]¶
- Yields:
A context within which all the events added to this storage will be prefixed by the name scope.
- put_histogram(hist_name, hist_tensor, bins=1000)[source]¶
Create a histogram from a tensor.
- Parameters:
hist_name (str) – The name of the histogram to put into tensorboard.
hist_tensor (torch.Tensor) – A Tensor of arbitrary shape to be converted into a histogram.
bins (int) – Number of histogram bins.
- put_image(img_name, img_tensor)[source]¶
Add an img_tensor associated with img_name, to be shown on tensorboard.
- Parameters:
img_name (str) – The name of the image to put into tensorboard.
img_tensor (torch.Tensor or numpy.array) – An uint8 or float Tensor of shape [channel, height, width] where channel is 3. The image format should be RGB. The elements in img_tensor can either have values in [0, 1] (float32) or [0, 255] (uint8). The img_tensor will be visualized in tensorboard.
- put_scalar(name, value, smoothing_hint=True)[source]¶
Add a scalar value to the HistoryBuffer associated with name.
- Parameters:
smoothing_hint (bool) –
a ‘hint’ on whether this scalar is noisy and should be smoothed when logged. The hint will be accessible through
EventStorage.smoothing_hints()
. A writer may ignore the hint and apply custom smoothing rule.It defaults to True because most scalars we save need to be smoothed to provide any useful signal.
- put_scalars(*, smoothing_hint=True, **kwargs)[source]¶
Put multiple scalars from keyword arguments.
Examples
storage.put_scalars(loss=my_loss, accuracy=my_accuracy, smoothing_hint=True)
- class xmodaler.utils.file_io.PathHandler(async_executor: Optional[Executor] = None)[source]¶
Bases:
EventLogger
PathHandler is a base class that defines common I/O functionality for a URI protocol. It routes I/O for a generic URI which may look like “protocol://*” or a canonical filepath “/foo/bar/baz”.
- xmodaler.utils.file_io.PathManager[source]¶
This is a detectron2 project-specific PathManager. We try to stay away from global PathManager in fvcore as it introduces potential conflicts among other libraries.
- class xmodaler.utils.logger.Counter(**kwds)[source]¶
Bases:
dict
Dict subclass for counting hashable items. Sometimes called a bag or multiset. Elements are stored as dictionary keys and their counts are stored as dictionary values.
>>> c = Counter('abcdeabcdabcaba') # count elements from a string
>>> c.most_common(3) # three most common elements [('a', 5), ('b', 4), ('c', 3)] >>> sorted(c) # list all unique elements ['a', 'b', 'c', 'd', 'e'] >>> ''.join(sorted(c.elements())) # list elements with repetitions 'aaaaabbbbcccdde' >>> sum(c.values()) # total of all counts 15
>>> c['a'] # count of letter 'a' 5 >>> for elem in 'shazam': # update counts from an iterable ... c[elem] += 1 # by adding 1 to each element's count >>> c['a'] # now there are seven 'a' 7 >>> del c['b'] # remove all 'b' >>> c['b'] # now there are zero 'b' 0
>>> d = Counter('simsalabim') # make another counter >>> c.update(d) # add in the second counter >>> c['a'] # now there are nine 'a' 9
>>> c.clear() # empty the counter >>> c Counter()
Note: If a count is set to zero or reduced to zero, it will remain in the counter until the entry is deleted or the counter is cleared:
>>> c = Counter('aaabbc') >>> c['b'] -= 2 # reduce the count of 'b' by two >>> c.most_common() # 'b' is still in, but its count is zero [('a', 3), ('c', 1), ('b', 0)]
- __init__(**kwds)[source]¶
Create a new, empty Counter object. And if given, count elements from an input iterable. Or, initialize the count from another mapping of elements to their counts.
>>> c = Counter() # a new, empty counter >>> c = Counter('gallahad') # a new counter from an iterable >>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping >>> c = Counter(a=4, b=2) # a new counter from keyword args
- elements()[source]¶
Iterator over elements repeating each as many times as its count.
>>> c = Counter('ABCABC') >>> sorted(c.elements()) ['A', 'A', 'B', 'B', 'C', 'C']
# Knuth’s example for prime factors of 1836: 2**2 * 3**3 * 17**1 >>> prime_factors = Counter({2: 2, 3: 3, 17: 1}) >>> product = 1 >>> for factor in prime_factors.elements(): # loop over factors … product *= factor # and multiply them >>> product 1836
Note, if an element’s count has been set to zero or is a negative number, elements() will ignore it.
- classmethod fromkeys(iterable, v=None)[source]¶
Create a new dictionary with keys from iterable and values set to value.
- most_common(n=None)[source]¶
List the n most common elements and their counts from the most common to the least. If n is None, then list all element counts.
>>> Counter('abcdeabcdabcaba').most_common(3) [('a', 5), ('b', 4), ('c', 3)]
- subtract(**kwds)[source]¶
Like dict.update() but subtracts counts instead of replacing them. Counts can be reduced below zero. Both the inputs and outputs are allowed to contain zero and negative counts.
Source can be an iterable, a dictionary, or another Counter instance.
>>> c = Counter('which') >>> c.subtract('witch') # subtract elements from another iterable >>> c.subtract(Counter('watch')) # subtract elements from another counter >>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch 0 >>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch -1
- update(**kwds)[source]¶
Like dict.update() but add counts instead of replacing them.
Source can be an iterable, a dictionary, or another Counter instance.
>>> c = Counter('which') >>> c.update('witch') # add elements from another iterable >>> d = Counter('watch') >>> c.update(d) # add elements from another counter >>> c['h'] # four 'h' in which, witch, and watch 4
- xmodaler.utils.logger.colored(text: str, color: str | None = None, on_color: str | None = None, attrs: Iterable[str] | None = None) str [source]¶
Colorize text.
- Available text colors:
black, red, green, yellow, blue, magenta, cyan, white, light_grey, dark_grey, light_red, light_green, light_yellow, light_blue, light_magenta, light_cyan.
- Available text highlights:
on_black, on_red, on_green, on_yellow, on_blue, on_magenta, on_cyan, on_white, on_light_grey, on_dark_grey, on_light_red, on_light_green, on_light_yellow, on_light_blue, on_light_magenta, on_light_cyan.
- Available attributes:
bold, dark, underline, blink, reverse, concealed.
Example
colored(‘Hello, World!’, ‘red’, ‘on_black’, [‘bold’, ‘blink’]) colored(‘Hello, World!’, ‘green’)
- xmodaler.utils.logger.create_small_table(small_dict)[source]¶
Create a small table using the keys of small_dict as headers. This is only suitable for small dictionaries.
- Parameters:
small_dict (dict) – a result dictionary of only a few items.
- Returns:
the table as a string.
- Return type:
str
- xmodaler.utils.logger.log_every_n(lvl, msg, n=1, *, name=None)[source]¶
Log once per n times.
- Parameters:
lvl (int) – the logging level
msg (str) –
n (int) –
name (str) – name of the logger to use. Will use the caller’s module by default.
- xmodaler.utils.logger.log_every_n_seconds(lvl, msg, n=1, *, name=None)[source]¶
Log no more than once per n seconds.
- Parameters:
lvl (int) – the logging level
msg (str) –
n (int) –
name (str) – name of the logger to use. Will use the caller’s module by default.
- xmodaler.utils.logger.log_first_n(lvl, msg, n=1, *, name=None, key='caller')[source]¶
Log only for the first n times.
- Parameters:
lvl (int) – the logging level
msg (str) –
n (int) –
name (str) – name of the logger to use. Will use the caller’s module by default.
key (str or tuple[str]) – the string(s) can be one of “caller” or “message”, which defines how to identify duplicated logs. For example, if called with n=1, key=”caller”, this function will only log the first call from the same caller, regardless of the message content. If called with n=1, key=”message”, this function will log the same content only once, even if they are called from different places. If called with n=1, key=(“caller”, “message”), this function will not log only if the same caller has logged the same message before.
- xmodaler.utils.logger.setup_logger(output=None, distributed_rank=0, *, color=True, name='xmodaler', abbrev_name=None)[source]¶
Initialize the xmodaler logger and set its verbosity level to “DEBUG”.
- Parameters:
output (str) – a file name or a directory to save log. If None, will not save log file. If ends with “.txt” or “.log”, assumed to be a file name. Otherwise, logs will be saved to output/log.txt.
name (str) – the root module name of this logger
abbrev_name (str) – an abbreviation of the module, to avoid long names in logs. Set to “” to not log the root module in logs. By default, will abbreviate “xmodaler” to “d2” and leave other modules unchanged.
- Returns:
a logger
- Return type:
logging.Logger
- xmodaler.utils.logger.tabulate(tabular_data, headers=(), tablefmt='simple', floatfmt='g', intfmt='', numalign='default', stralign='default', missingval='', showindex='default', disable_numparse=False, colalign=None, maxcolwidths=None, rowalign=None, maxheadercolwidths=None)[source]¶
Format a fixed width table for pretty printing.
>>> print(tabulate([[1, 2.34], [-56, "8.999"], ["2", "10001"]])) --- --------- 1 2.34 -56 8.999 2 10001 --- ---------
The first required argument (tabular_data) can be a list-of-lists (or another iterable of iterables), a list of named tuples, a dictionary of iterables, an iterable of dictionaries, an iterable of dataclasses (Python 3.7+), a two-dimensional NumPy array, NumPy record array, or a Pandas’ dataframe.
Table headers¶
To print nice column headers, supply the second argument (headers):
headers can be an explicit list of column headers
if headers=”firstrow”, then the first row of data is used
if headers=”keys”, then dictionary keys or column indices are used
Otherwise a headerless table is produced.
If the number of headers is less than the number of columns, they are supposed to be names of the last columns. This is consistent with the plain-text format of R and Pandas’ dataframes.
>>> print(tabulate([["sex","age"],["Alice","F",24],["Bob","M",19]], ... headers="firstrow")) sex age ----- ----- ----- Alice F 24 Bob M 19
By default, pandas.DataFrame data have an additional column called row index. To add a similar column to all other types of data, use showindex=”always” or showindex=True. To suppress row indices for all types of data, pass showindex=”never” or `showindex=False. To add a custom row index column, pass showindex=some_iterable.
>>> print(tabulate([["F",24],["M",19]], showindex="always")) - - -- 0 F 24 1 M 19 - - --
Column alignment¶
tabulate tries to detect column types automatically, and aligns the values properly. By default it aligns decimal points of the numbers (or flushes integer numbers to the right), and flushes everything else to the left. Possible column alignments (numalign, stralign) are: “right”, “center”, “left”, “decimal” (only for numalign), and None (to disable alignment).
Table formats¶
intfmt is a format specification used for columns which contain numeric data without a decimal point. This can also be a list or tuple of format strings, one per column.
floatfmt is a format specification used for columns which contain numeric data with a decimal point. This can also be a list or tuple of format strings, one per column.
None values are replaced with a missingval string (like floatfmt, this can also be a list of values for different columns):
>>> print(tabulate([["spam", 1, None], ... ["eggs", 42, 3.14], ... ["other", None, 2.7]], missingval="?")) ----- -- ---- spam 1 ? eggs 42 3.14 other ? 2.7 ----- -- ----
Various plain-text table formats (tablefmt) are supported: ‘plain’, ‘simple’, ‘grid’, ‘pipe’, ‘orgtbl’, ‘rst’, ‘mediawiki’, ‘latex’, ‘latex_raw’, ‘latex_booktabs’, ‘latex_longtable’ and tsv. Variable `tabulate_formats`contains the list of currently supported formats.
“plain” format doesn’t use any pseudographics to draw tables, it separates columns with a double space:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "plain")) strings numbers spam 41.9999 eggs 451
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tablefmt="plain")) spam 41.9999 eggs 451
“simple” format is like Pandoc simple_tables:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "simple")) strings numbers --------- --------- spam 41.9999 eggs 451
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tablefmt="simple")) ---- -------- spam 41.9999 eggs 451 ---- --------
“grid” is similar to tables produced by Emacs table.el package or Pandoc grid_tables:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "grid")) +-----------+-----------+ | strings | numbers | +===========+===========+ | spam | 41.9999 | +-----------+-----------+ | eggs | 451 | +-----------+-----------+
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tablefmt="grid")) +------+----------+ | spam | 41.9999 | +------+----------+ | eggs | 451 | +------+----------+
“simple_grid” draws a grid using single-line box-drawing characters:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "simple_grid")) ┌───────────┬───────────┐ │ strings │ numbers │ ├───────────┼───────────┤ │ spam │ 41.9999 │ ├───────────┼───────────┤ │ eggs │ 451 │ └───────────┴───────────┘
“rounded_grid” draws a grid using single-line box-drawing characters with rounded corners:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "rounded_grid")) ╭───────────┬───────────╮ │ strings │ numbers │ ├───────────┼───────────┤ │ spam │ 41.9999 │ ├───────────┼───────────┤ │ eggs │ 451 │ ╰───────────┴───────────╯
“heavy_grid” draws a grid using bold (thick) single-line box-drawing characters:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "heavy_grid")) ┏━━━━━━━━━━━┳━━━━━━━━━━━┓ ┃ strings ┃ numbers ┃ ┣━━━━━━━━━━━╋━━━━━━━━━━━┫ ┃ spam ┃ 41.9999 ┃ ┣━━━━━━━━━━━╋━━━━━━━━━━━┫ ┃ eggs ┃ 451 ┃ ┗━━━━━━━━━━━┻━━━━━━━━━━━┛
“mixed_grid” draws a grid using a mix of light (thin) and heavy (thick) lines box-drawing characters:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "mixed_grid")) ┍━━━━━━━━━━━┯━━━━━━━━━━━┑ │ strings │ numbers │ ┝━━━━━━━━━━━┿━━━━━━━━━━━┥ │ spam │ 41.9999 │ ├───────────┼───────────┤ │ eggs │ 451 │ ┕━━━━━━━━━━━┷━━━━━━━━━━━┙
“double_grid” draws a grid using double-line box-drawing characters:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "double_grid")) ╔═══════════╦═══════════╗ ║ strings ║ numbers ║ ╠═══════════╬═══════════╣ ║ spam ║ 41.9999 ║ ╠═══════════╬═══════════╣ ║ eggs ║ 451 ║ ╚═══════════╩═══════════╝
“fancy_grid” draws a grid using a mix of single and double-line box-drawing characters:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "fancy_grid")) ╒═══════════╤═══════════╕ │ strings │ numbers │ ╞═══════════╪═══════════╡ │ spam │ 41.9999 │ ├───────────┼───────────┤ │ eggs │ 451 │ ╘═══════════╧═══════════╛
“outline” is the same as the “grid” format but doesn’t draw lines between rows:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "outline")) +-----------+-----------+ | strings | numbers | +===========+===========+ | spam | 41.9999 | | eggs | 451 | +-----------+-----------+
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tablefmt="outline")) +------+----------+ | spam | 41.9999 | | eggs | 451 | +------+----------+
“simple_outline” is the same as the “simple_grid” format but doesn’t draw lines between rows:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "simple_outline")) ┌───────────┬───────────┐ │ strings │ numbers │ ├───────────┼───────────┤ │ spam │ 41.9999 │ │ eggs │ 451 │ └───────────┴───────────┘
“rounded_outline” is the same as the “rounded_grid” format but doesn’t draw lines between rows:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "rounded_outline")) ╭───────────┬───────────╮ │ strings │ numbers │ ├───────────┼───────────┤ │ spam │ 41.9999 │ │ eggs │ 451 │ ╰───────────┴───────────╯
“heavy_outline” is the same as the “heavy_grid” format but doesn’t draw lines between rows:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "heavy_outline")) ┏━━━━━━━━━━━┳━━━━━━━━━━━┓ ┃ strings ┃ numbers ┃ ┣━━━━━━━━━━━╋━━━━━━━━━━━┫ ┃ spam ┃ 41.9999 ┃ ┃ eggs ┃ 451 ┃ ┗━━━━━━━━━━━┻━━━━━━━━━━━┛
“mixed_outline” is the same as the “mixed_grid” format but doesn’t draw lines between rows:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "mixed_outline")) ┍━━━━━━━━━━━┯━━━━━━━━━━━┑ │ strings │ numbers │ ┝━━━━━━━━━━━┿━━━━━━━━━━━┥ │ spam │ 41.9999 │ │ eggs │ 451 │ ┕━━━━━━━━━━━┷━━━━━━━━━━━┙
“double_outline” is the same as the “double_grid” format but doesn’t draw lines between rows:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "double_outline")) ╔═══════════╦═══════════╗ ║ strings ║ numbers ║ ╠═══════════╬═══════════╣ ║ spam ║ 41.9999 ║ ║ eggs ║ 451 ║ ╚═══════════╩═══════════╝
“fancy_outline” is the same as the “fancy_grid” format but doesn’t draw lines between rows:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "fancy_outline")) ╒═══════════╤═══════════╕ │ strings │ numbers │ ╞═══════════╪═══════════╡ │ spam │ 41.9999 │ │ eggs │ 451 │ ╘═══════════╧═══════════╛
“pipe” is like tables in PHP Markdown Extra extension or Pandoc pipe_tables:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "pipe")) | strings | numbers | |:----------|----------:| | spam | 41.9999 | | eggs | 451 |
“presto” is like tables produce by the Presto CLI:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "presto")) strings | numbers -----------+----------- spam | 41.9999 eggs | 451
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tablefmt="pipe")) |:-----|---------:| | spam | 41.9999 | | eggs | 451 |
“orgtbl” is like tables in Emacs org-mode and orgtbl-mode. They are slightly different from “pipe” format by not using colons to define column alignment, and using a “+” sign to indicate line intersections:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "orgtbl")) | strings | numbers | |-----------+-----------| | spam | 41.9999 | | eggs | 451 |
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tablefmt="orgtbl")) | spam | 41.9999 | | eggs | 451 |
“rst” is like a simple table format from reStructuredText; please note that reStructuredText accepts also “grid” tables:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "rst")) ========= ========= strings numbers ========= ========= spam 41.9999 eggs 451 ========= =========
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tablefmt="rst")) ==== ======== spam 41.9999 eggs 451 ==== ========
“mediawiki” produces a table markup used in Wikipedia and on other MediaWiki-based sites:
>>> print(tabulate([["strings", "numbers"], ["spam", 41.9999], ["eggs", "451.0"]], ... headers="firstrow", tablefmt="mediawiki")) {| class="wikitable" style="text-align: left;" |+ <!-- caption --> |- ! strings !! align="right"| numbers |- | spam || align="right"| 41.9999 |- | eggs || align="right"| 451 |}
“html” produces HTML markup as an html.escape’d str with a ._repr_html_ method so that Jupyter Lab and Notebook display the HTML and a .str property so that the raw HTML remains accessible the unsafehtml table format can be used if an unescaped HTML format is required:
>>> print(tabulate([["strings", "numbers"], ["spam", 41.9999], ["eggs", "451.0"]], ... headers="firstrow", tablefmt="html")) <table> <thead> <tr><th>strings </th><th style="text-align: right;"> numbers</th></tr> </thead> <tbody> <tr><td>spam </td><td style="text-align: right;"> 41.9999</td></tr> <tr><td>eggs </td><td style="text-align: right;"> 451 </td></tr> </tbody> </table>
“latex” produces a tabular environment of LaTeX document markup:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tablefmt="latex")) \begin{tabular}{lr} \hline spam & 41.9999 \\ eggs & 451 \\ \hline \end{tabular}
“latex_raw” is similar to “latex”, but doesn’t escape special characters, such as backslash and underscore, so LaTeX commands may embedded into cells’ values:
>>> print(tabulate([["spam$_9$", 41.9999], ["\\emph{eggs}", "451.0"]], tablefmt="latex_raw")) \begin{tabular}{lr} \hline spam$_9$ & 41.9999 \\ \emph{eggs} & 451 \\ \hline \end{tabular}
“latex_booktabs” produces a tabular environment of LaTeX document markup using the booktabs.sty package:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tablefmt="latex_booktabs")) \begin{tabular}{lr} \toprule spam & 41.9999 \\ eggs & 451 \\ \bottomrule \end{tabular}
“latex_longtable” produces a tabular environment that can stretch along multiple pages, using the longtable package for LaTeX.
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tablefmt="latex_longtable")) \begin{longtable}{lr} \hline spam & 41.9999 \\ eggs & 451 \\ \hline \end{longtable}
Number parsing¶
By default, anything which can be parsed as a number is a number. This ensures numbers represented as strings are aligned properly. This can lead to weird results for particular strings such as specific git SHAs e.g. “42992e1” will be parsed into the number 429920 and aligned as such.
To completely disable number parsing (and alignment), use disable_numparse=True. For more fine grained control, a list column indices is used to disable number parsing only on those columns e.g. disable_numparse=[0, 2] would disable number parsing only on the first and third columns.
Column Widths and Auto Line Wrapping¶
Tabulate will, by default, set the width of each column to the length of the longest element in that column. However, in situations where fields are expected to reasonably be too long to look good as a single line, tabulate can help automate word wrapping long fields for you. Use the parameter maxcolwidth to provide a list of maximal column widths
>>> print(tabulate( [('1', 'John Smith', 'This is a rather long description that might look better if it is wrapped a bit')], headers=("Issue Id", "Author", "Description"), maxcolwidths=[None, None, 30], tablefmt="grid" )) +------------+------------+-------------------------------+ | Issue Id | Author | Description | +============+============+===============================+ | 1 | John Smith | This is a rather long | | | | description that might look | | | | better if it is wrapped a bit | +------------+------------+-------------------------------+
Header column width can be specified in a similar way using maxheadercolwidth
- xmodaler.utils.memory.retry_if_cuda_oom(func)[source]¶
Makes a function retry itself after encountering pytorch’s CUDA OOM error. It will first retry after calling torch.cuda.empty_cache().
If that still fails, it will then retry by trying to convert inputs to CPUs. In this case, it expects the function to dispatch to CPU implementation. The return values may become CPU tensors as well and it’s user’s responsibility to convert it back to CUDA tensor if needed.
- Parameters:
func – a stateless callable that takes tensor-like objects as arguments
- Returns:
a callable which retries func if OOM is encountered.
Examples:
output = retry_if_cuda_oom(some_torch_function)(input1, input2) # output may be on CPU even if inputs are on GPU
Note
When converting inputs to CPU, it will only look at each argument and check if it has .device and .to for conversion. Nested structures of tensors are not supported.
Since the function might be called more than once, it has to be stateless.
- class xmodaler.utils.registry.Registry(name: str)[source]¶
Bases:
Iterable
[Tuple
[str
,Any
]]The registry that provides name -> object mapping, to support third-party users’ custom modules.
To create a registry (e.g. a backbone registry):
BACKBONE_REGISTRY = Registry('BACKBONE')
To register an object:
@BACKBONE_REGISTRY.register() class MyBackbone(): ...
Or:
BACKBONE_REGISTRY.register(MyBackbone)
- xmodaler.utils.registry.locate(name: str) Any [source]¶
Locate and return an object
x
using an input string{x.__module__}.{x.__qualname__}
, such as “module.submodule.class_name”.Raise Exception if it cannot be found.
- class xmodaler.utils.serialize.PicklableWrapper(obj)[source]¶
Bases:
object
Wrap an object to make it more picklable, note that it uses heavy weight serialization libraries that are slower than pickle. It’s best to use it only on closures (which are usually not picklable).
This is a simplified version of https://github.com/joblib/joblib/blob/master/joblib/externals/loky/cloudpickle_wrapper.py