Skip to content

Commit

Permalink
add docs for v0.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
yaoyaoding committed Sep 28, 2023
1 parent afdb32c commit d6b821b
Show file tree
Hide file tree
Showing 447 changed files with 93,216 additions and 1 deletion.
2 changes: 1 addition & 1 deletion docs/stable
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/environment.pickle
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/gallery/index.doctree
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/genindex.doctree
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/hidet-script/index.doctree
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/index.doctree
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/notes/operator-cache.doctree
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/python_api/cuda.doctree
Binary file not shown.
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/python_api/driver.doctree
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/python_api/index.doctree
Binary file not shown.
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/python_api/ir/expr.doctree
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/python_api/ir/func.doctree
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/python_api/ir/index.doctree
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/python_api/ir/stmt.doctree
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/python_api/ir/task.doctree
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/python_api/ir/type.doctree
Binary file not shown.
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/python_api/option.doctree
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/python_api/root.doctree
Binary file not shown.
Binary file not shown.
Binary file added docs/v0.3.0/doctrees/python_api/tensor.doctree
Binary file not shown.
Binary file not shown.
Binary file not shown.
4 changes: 4 additions & 0 deletions docs/v0.3.0/html/.buildinfo
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: e33f866f68b391924ffcfe08ddc7cd87
tags: 645f666f9bcd5a90fca523b33c5a78b7
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
"""
.. _add-operator-resolve-rule:
Add Operator Resolve Rule
=========================
This is a tutorial introduces the `operator resolving mechanism` and how to add a new operator resolve rule. An operator
resolve rule is used to resolve an operator to other operators. Usually, we would resolve a more generic operator to
more specific and efficient operators. The operator resolving rules allow us to reuse existing highly-optimized
operators to implement a new operator, while organizing the operators in a more modular way.
Operator Resolving
------------------
The core idea of the **operator resolving** is to resolve a generic operator to more specific and high-optimized
operators. When we define a new operator, we can also attach an operator resolve rule to it. The rule defines how to
resolve the operator to other operators with the same semantics. After the operator is resolved, the original operator
will be replaced by the resolved operators. This process is transparent to the user and is done automatically by a pass
when we optimize a flow graph.
There are typical two scenarios that we need to resolve an operator to other operators:
- **Resolve a generic operator to specialized variants**: We can provide a generic operator and lots of its specialized
variants. When optimizing the model, we can resolve the generic operator to the most suitable specialized operator.
For example, in Hidet, we provided a generic :py:func:`~hidet.ops.matmul` operator with the same semantics as
the numpy equivalent :py:data:`numpy.matmul`. This operator is a generic operator and is scheduled automatically by
our auto-scheduler, thus it is not very efficient. But we also provided a lot of specialized variants of the operators
such as highly-optimized :py:func:`~hidet.ops.batch_matmul` that only accepts :math:`A=[B, M, K]` and
:math:`B=[B, K, N]`. During the operator resolving, we first reshape and broadcast the input tensors to align the
input shapes with the specialized operator, then use the specialized operator to compute the result, and finally
reshape the output tensor to get the correct output shape.
.. tip::
:class: margin
During the operator resolving, we might introduce some extra operators to adjust the input tensors (e.g.,
:func:`~hidet.ops.reshape`, :func:`~hidet.ops.broadcast`, :func:`~hidet.ops.transpose`, etc.).
These extra operators are usually fused into the resolved operators or surrounding operators of the original operator
in the later optimization pass. Thus, the extra overhead is usually negligible.
.. figure:: /_static/img/resolve-example-matmul.svg
:align: center
:scale: 70%
The resolve rule for `Matmul` operator.
- **Reuse a new operator to existing operators**: When we add a new operator and the new operator can be implemented by
existing operators, we can use a resolve rule to resolve the new operator to the existing highly-optimized operators
to reduce the development effort.
.. figure:: /_static/img/resolve-example-conv2d.svg
:align: center
:scale: 70%
This rule resolves the generic :func:`~hidet.ops.conv2d` operator to matrix multiplication using the img2col
algorithm.
The operator resolving pass would repeat the resolving process until no more operators can be resolved. Thus, in the
conv2d example, we will first resolve :func:`~hidet.ops.conv2d` to :func:`~hidet.ops.matmul`, and then
to :func:`~hidet.ops.batch_matmul`.
Add Operator Resolve Rule
-------------------------
To add a resolve rule to an operator, we need to
#. define a subclass of :class:`~hidet.graph.transforms.resolve_variant.ResolveRule` and then
#. register the rule by decorating it with :func:`~hidet.graph.transforms.resolve_variant.register_resolve_rule`.
In the following example, we resolve the :func:`~hidet.ops.pow` operator to normal multiplications if the exponent
is a constant integer 3.
Before we start, let's have a look at the original behavior when there is no such resolve rule.
"""
import hidet

a = hidet.symbol(shape=[2, 3], device='cuda')
b = hidet.ops.pow(a, hidet.asarray(3, device='cuda'))
graph = hidet.trace_from(b, inputs=[a])
print('Original graph:')
print(graph)

print('Optimized graph without resolving Pow:')
graph_opt = hidet.graph.optimize(graph)
print(graph_opt)

# %%
# The original graph contains a :func:`~hidet.ops.pow` operator, and the optimized graph is the same as the
# original graph. Now let's add the resolve rule and see what happens.

from typing import Optional, List
from hidet import Tensor
from hidet.graph.ops.arithmetic import PowOp
from hidet.graph.transforms import register_resolve_rule, ResolveRule


@register_resolve_rule(PowOp)
class PowResolveRule(ResolveRule):
def resolve(self, op: PowOp) -> Optional[List[Tensor]]:
a: Tensor = op.inputs[0] # get the base tensor
b: Tensor = op.inputs[1] # get the exponent tensor
if not b.is_symbolic() and len(b.shape) == 0 and int(b) == 3:
# if the exponent is a constant integer 3, resolve the operator to a * a * a
return [a * a * a]
# otherwise, return None to indicate that the operator cannot be resolved
# and the original operator will be kept
return None


# optimize the original graph again
# the Pow operator will be resolved to a * a * a
# after that, the two multiplications will be fused into one operator
graph_opt_new = hidet.graph.optimize(graph)
print('Optimized graph after resolving Pow:')
print(graph_opt_new)


# %%
# .. seealso::
#
# :func:`~hidet.graph.transforms.resolve_variant.register_resolve_rule`,
# :class:`~hidet.graph.transforms.resolve_variant.ResolveRule` for the details of the resolve rule.
#
# Summary
# -------
# In this tutorial, we learned how to resolve an operator to other operators. We also learned how to add a resolve
# rule to an operator. The resolve rule is a powerful tool to reuse existing operators to implement new operators.
# We can also use it to resolve a generic operator to more specialized variants.
#
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n# Hello World!\n\nIn this example, we will show you how to use hidet to write a simple \"Hello World\" program.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Hidet is a deep learning compiler implemented in python. Let's import it first.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import hidet"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Hidet caches all its generated source code and binary in its cache directory. We can set the cache directory\nto a local directory ``./outs/cache`` so that you can check the generated code and binary.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"hidet.option.cache_dir('./outs/cache')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The ``hidet.lang`` submodule implements the Hidet Script domain specific language.\nIn this example, we will use ``attrs`` variable and ``printf`` function from ``hidet.lang``.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from hidet.lang import attrs, printf"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A **script module** is a compilation unit that contains a list of functions defined in it. Inside a script module,\nwe can use ``hidet.script`` to define a hidet script function. The following example defines a function named\n``launch`` that prints a message to the standard output.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"with hidet.script_module() as script_module:\n\n # we use `hidet.script` to decorate a python function to define a hidet script function.\n @hidet.script\n def launch():\n # we use `hidet.lang.attrs` to set the attributes of the function.\n # the following line specify this hidet script function is a public function.\n attrs.func_kind = 'public'\n\n # print a message to the standard output.\n printf(\"Hello World!\\n\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"With the script module defined, we can build the script module with ``build()`` method. The returned ``module`` is\nan instance of ``hidet.runtime.CompiledModule``, which contains the compiled binary.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"module = script_module.build()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can directly call the compiled module, in this case the 'launch' function would be invoked.\n\n<div class=\"alert alert-info\"><h4>Note</h4><p>:class: margin\n\n The printed message has not been captured by our documentation generation tool (i.e., sphinx).\n If you run the script by yourself, you will see the message printed out in your console.</p></div>\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"module()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can also explicitly specify the function to be invoked using ``module['func_name'](args)``.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"module['launch']()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"you can access the source code of the compiled module using ``module.source()``.\n\n<div class=\"alert alert-info\"><h4>Note</h4><p>:class: margin\n\n The function in the source code has a prefix ``hidet_``, which is used to avoid name conflict with standard\n library functions.</p></div>\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"print(module.source(color=True))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.17"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""
Hello World!
============
In this example, we will show you how to use hidet to write a simple "Hello World" program.
"""
# %%
# Hidet is a deep learning compiler implemented in python. Let's import it first.
import hidet

# %%
# Hidet caches all its generated source code and binary in its cache directory. We can set the cache directory
# to a local directory ``./outs/cache`` so that you can check the generated code and binary.
hidet.option.cache_dir('./outs/cache')

# %%
# The ``hidet.lang`` submodule implements the Hidet Script domain specific language.
# In this example, we will use ``attrs`` variable and ``printf`` function from ``hidet.lang``.
from hidet.lang import attrs, printf

# %%
# A **script module** is a compilation unit that contains a list of functions defined in it. Inside a script module,
# we can use ``hidet.script`` to define a hidet script function. The following example defines a function named
# ``launch`` that prints a message to the standard output.

with hidet.script_module() as script_module:

# we use `hidet.script` to decorate a python function to define a hidet script function.
@hidet.script
def launch():
# we use `hidet.lang.attrs` to set the attributes of the function.
# the following line specify this hidet script function is a public function.
attrs.func_kind = 'public'

# print a message to the standard output.
printf("Hello World!\n")


# %%
# With the script module defined, we can build the script module with ``build()`` method. The returned ``module`` is
# an instance of ``hidet.runtime.CompiledModule``, which contains the compiled binary.
module = script_module.build()

# %%
# We can directly call the compiled module, in this case the 'launch' function would be invoked.
#
# .. note::
# :class: margin
#
# The printed message has not been captured by our documentation generation tool (i.e., sphinx).
# If you run the script by yourself, you will see the message printed out in your console.
module()

# %%
# We can also explicitly specify the function to be invoked using ``module['func_name'](args)``.
module['launch']()

# %%
# you can access the source code of the compiled module using ``module.source()``.
#
# .. note::
# :class: margin
#
# The function in the source code has a prefix ``hidet_``, which is used to avoid name conflict with standard
# library functions.
print(module.source(color=True))
Loading

0 comments on commit d6b821b

Please sign in to comment.