Unverified Commit a449d8b1 by Tianqi Chen Committed by GitHub

[DOCS] Fix sphinx precheck (#4967)

* [DOCS] Fix sphinx precheck

* ignore keras warnings

* Remove more warnings
parent 7ccb4363
.. Licensed to the Apache Software Foundation (ASF) under one .. Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file or more contributor license agreements. See the NOTICE file
distributed with this work for additional information distributed with this work for additional information
...@@ -63,7 +64,7 @@ Hence, it is often easy to reason about ADTs. ...@@ -63,7 +64,7 @@ Hence, it is often easy to reason about ADTs.
Below is a simple example of defining an ADT and using it in a function Below is a simple example of defining an ADT and using it in a function
via a match expression: via a match expression:
.. code-block:: python .. code-block::
# Defines an ADT named "Numbers" # Defines an ADT named "Numbers"
data Numbers { data Numbers {
...@@ -94,7 +95,7 @@ meaning that two ADTs with structurally identical constructors ...@@ -94,7 +95,7 @@ meaning that two ADTs with structurally identical constructors
will nevertheless be distinct data types from the point of view of will nevertheless be distinct data types from the point of view of
the typechecker. the typechecker.
.. code-block:: python .. code-block::
# structurally identical constructors to Numbers # structurally identical constructors to Numbers
data Numbers2 { data Numbers2 {
...@@ -117,7 +118,7 @@ can be polymorphic and take type parameters. ...@@ -117,7 +118,7 @@ can be polymorphic and take type parameters.
For example, one of the standard ADTs commonly used in functional For example, one of the standard ADTs commonly used in functional
programming languages is the optional type, defined here: programming languages is the optional type, defined here:
.. code-block:: python .. code-block::
# a is a type parameter # a is a type parameter
data Optional<a> { data Optional<a> {
...@@ -141,7 +142,7 @@ imply, an ADT instance is thus given a type that contains the ...@@ -141,7 +142,7 @@ imply, an ADT instance is thus given a type that contains the
concrete type arguments for that instance, ensuring the information is concrete type arguments for that instance, ensuring the information is
kept around. Let the below example illustrate: kept around. Let the below example illustrate:
.. code-block:: python .. code-block::
# the signature for option indicates the type argument # the signature for option indicates the type argument
def @inc_scalar(%opt : Optional[Tensor[(), int32]]) -> Tensor[(), int32] { def @inc_scalar(%opt : Optional[Tensor[(), int32]]) -> Tensor[(), int32] {
...@@ -198,7 +199,7 @@ Many commonly used ADTs involve recursion; some of these are given ...@@ -198,7 +199,7 @@ Many commonly used ADTs involve recursion; some of these are given
in `Common ADT Uses`_. As an example here, we will in `Common ADT Uses`_. As an example here, we will
examine the list ADT, ubiquitous in functional languages: examine the list ADT, ubiquitous in functional languages:
.. code-block:: python .. code-block::
data List<a> { data List<a> {
Nil : () -> List Nil : () -> List
...@@ -216,7 +217,7 @@ end of the list is reached, which can be indicated with a :code:`Nil` ...@@ -216,7 +217,7 @@ end of the list is reached, which can be indicated with a :code:`Nil`
Lists represented in this manner can easily be recursively processed. Lists represented in this manner can easily be recursively processed.
For example, the following function sums a list of integers: For example, the following function sums a list of integers:
.. code-block:: python .. code-block::
def @list_sum(%l : List[Tensor[(), int32]]) -> Tensor[(), int32] { def @list_sum(%l : List[Tensor[(), int32]]) -> Tensor[(), int32] {
match(%l) { match(%l) {
...@@ -250,7 +251,7 @@ and the second has a :code:`Cons` constructor pattern that uses variable pattern ...@@ -250,7 +251,7 @@ and the second has a :code:`Cons` constructor pattern that uses variable pattern
The below example uses a wildcard pattern to ignore one of the arguments to :code:`Cons`: The below example uses a wildcard pattern to ignore one of the arguments to :code:`Cons`:
.. code-block:: python .. code-block::
def @first<a>(%l : List[a]) -> Optional[a] { def @first<a>(%l : List[a]) -> Optional[a] {
match(%l) { match(%l) {
...@@ -262,7 +263,7 @@ The below example uses a wildcard pattern to ignore one of the arguments to :cod ...@@ -262,7 +263,7 @@ The below example uses a wildcard pattern to ignore one of the arguments to :cod
Here, a constructor pattern is nested inside another constructor pattern to avoid nested match expressions for a list option. Here, a constructor pattern is nested inside another constructor pattern to avoid nested match expressions for a list option.
A top-level wildcard pattern is also used to handle all cases that do not match the first clause: A top-level wildcard pattern is also used to handle all cases that do not match the first clause:
.. code-block:: python .. code-block::
def @second_opt<a>(%ll : Optional[List[a]]) -> Optional[a] { def @second_opt<a>(%ll : Optional[List[a]]) -> Optional[a] {
match(%ll) { match(%ll) {
...@@ -281,7 +282,7 @@ Note that a match expression checks its patterns in the order the cases are list ...@@ -281,7 +282,7 @@ Note that a match expression checks its patterns in the order the cases are list
that matches the input value is the one that is evaluated. Here, a top-level variable pattern binds the whole that matches the input value is the one that is evaluated. Here, a top-level variable pattern binds the whole
input value: input value:
.. code-block:: python .. code-block::
def @match_order_beware<a>(%l : List[a]) -> List[a] { def @match_order_beware<a>(%l : List[a]) -> List[a] {
match(%l) { match(%l) {
...@@ -312,7 +313,7 @@ list comprehensions and certain library functions in Python. Below are very comm ...@@ -312,7 +313,7 @@ list comprehensions and certain library functions in Python. Below are very comm
through lists, which are included in Relay's Prelude. (These have all been extensively characterized through lists, which are included in Relay's Prelude. (These have all been extensively characterized
in the functional programming literature, and we do not attempt to reproduce that work in this document.) in the functional programming literature, and we do not attempt to reproduce that work in this document.)
.. code-block:: python .. code-block::
# Map: for [h1, h2, ..., hn] returns [f(h1), f(h2), ..., f(hn)] # Map: for [h1, h2, ..., hn] returns [f(h1), f(h2), ..., f(hn)]
def @map<a, b>(%f : fn(a) -> b, %l : List[a]) -> List[b] { def @map<a, b>(%f : fn(a) -> b, %l : List[a]) -> List[b] {
...@@ -341,7 +342,7 @@ in the functional programming literature, and we do not attempt to reproduce tha ...@@ -341,7 +342,7 @@ in the functional programming literature, and we do not attempt to reproduce tha
Using these iteration constructs, many common operations over lists can be expressed compactly. Using these iteration constructs, many common operations over lists can be expressed compactly.
For example, the following map doubles all members of a list: For example, the following map doubles all members of a list:
.. code-block:: python .. code-block::
# directly written # directly written
def @double(%l : List[Tensor[(), int32]]) -> List[Tensor[(), int32]] { def @double(%l : List[Tensor[(), int32]]) -> List[Tensor[(), int32]] {
...@@ -356,7 +357,7 @@ For example, the following map doubles all members of a list: ...@@ -356,7 +357,7 @@ For example, the following map doubles all members of a list:
The following right fold concatenates two lists: The following right fold concatenates two lists:
.. code-block:: python .. code-block::
# directly written # directly written
def @concat<a>(%l1 : List[a], %l2 : List[a]) -> List[a] { def @concat<a>(%l1 : List[a], %l2 : List[a]) -> List[a] {
...@@ -371,7 +372,7 @@ The following right fold concatenates two lists: ...@@ -371,7 +372,7 @@ The following right fold concatenates two lists:
The following left fold flattens a list of lists (using concatenation): The following left fold flattens a list of lists (using concatenation):
.. code-block:: python .. code-block::
# directly written # directly written
def @flatten<a>(%ll : List[List[a]]) -> List[a] { def @flatten<a>(%ll : List[List[a]]) -> List[a] {
...@@ -401,13 +402,13 @@ First let us suppose that we have a function corresponding to a trained recurren ...@@ -401,13 +402,13 @@ First let us suppose that we have a function corresponding to a trained recurren
cell, which takes in a past state and an input value and returns a new state and output value. In cell, which takes in a past state and an input value and returns a new state and output value. In
Relay, this would have the following signature: Relay, this would have the following signature:
.. code-block:: python .. code-block::
@cell : fn<state_type, in_type, out_type>(state_type, in_type) -> (state_type, out_type) @cell : fn<state_type, in_type, out_type>(state_type, in_type) -> (state_type, out_type)
We might consider a ReLU cell as a simple concrete example, with a trained version below: We might consider a ReLU cell as a simple concrete example, with a trained version below:
.. code-block:: python .. code-block::
def @linear(%x, %w, %b) { %w*%x + %b } def @linear(%x, %w, %b) { %w*%x + %b }
...@@ -429,7 +430,7 @@ We might consider a ReLU cell as a simple concrete example, with a trained versi ...@@ -429,7 +430,7 @@ We might consider a ReLU cell as a simple concrete example, with a trained versi
Following Olah's example, we can encode a sequence (list) of inputs with the following left fold: Following Olah's example, we can encode a sequence (list) of inputs with the following left fold:
.. code-block:: python .. code-block::
def @encode<state_type, in_type, out_type>(%cell, %input : List[in_type], %init : state_type) -> state_type { def @encode<state_type, in_type, out_type>(%cell, %input : List[in_type], %init : state_type) -> state_type {
# not using the output # not using the output
...@@ -439,7 +440,7 @@ Following Olah's example, we can encode a sequence (list) of inputs with the fol ...@@ -439,7 +440,7 @@ Following Olah's example, we can encode a sequence (list) of inputs with the fol
Using an *unfold* iterator (from Haskell's standard library), the same cell could be used to make Using an *unfold* iterator (from Haskell's standard library), the same cell could be used to make
a generator network (which takes a single input and produces a sequence of outputs): a generator network (which takes a single input and produces a sequence of outputs):
.. code-block:: python .. code-block::
# included in Relay's Prelude # included in Relay's Prelude
def @unfoldr<a, b>(%f : fn(b) -> Optional[(a, b)], %z : b) -> List[a] { def @unfoldr<a, b>(%f : fn(b) -> Optional[(a, b)], %z : b) -> List[a] {
...@@ -468,7 +469,7 @@ a generator network (which takes a single input and produces a sequence of outpu ...@@ -468,7 +469,7 @@ a generator network (which takes a single input and produces a sequence of outpu
An accumulating map (a fold that simultaneously updates an accumulator value and a list An accumulating map (a fold that simultaneously updates an accumulator value and a list
of outputs) can be used to write a general RNN (with an output for every input): of outputs) can be used to write a general RNN (with an output for every input):
.. code-block:: python .. code-block::
def @map_accumr<a, b, c>(%f : fn(a, b) -> (a, c), %acc : a, %l : List[b]) -> (a, List[c]) { def @map_accumr<a, b, c>(%f : fn(a, b) -> (a, c), %acc : a, %l : List[b]) -> (a, List[c]) {
match(%l) { match(%l) {
...@@ -500,7 +501,7 @@ Olah also gives an example of a bidirectional neural network, in which two sets ...@@ -500,7 +501,7 @@ Olah also gives an example of a bidirectional neural network, in which two sets
cells (which may have different weights) process the input in both directions and produce a cells (which may have different weights) process the input in both directions and produce a
single set of outputs. The following is a Relay implementation of that example: single set of outputs. The following is a Relay implementation of that example:
.. code-block:: python .. code-block::
# creates a list of tuples from two lists # creates a list of tuples from two lists
# included in Relay's Prelude # included in Relay's Prelude
......
...@@ -92,7 +92,7 @@ references to :code:`%a` in the inner scope refer to the later definition, while ...@@ -92,7 +92,7 @@ references to :code:`%a` in the inner scope refer to the later definition, while
references to :code:`%a` in the outer scope continue to refer to references to :code:`%a` in the outer scope continue to refer to
the first one. the first one.
.. code-block:: python .. code-block::
let %a = 1; let %a = 1;
let %b = 2 * %a; // %b = 2 let %b = 2 * %a; // %b = 2
...@@ -129,14 +129,14 @@ A definition minimally consists of the keyword :code:`fn`, an empty set of ...@@ -129,14 +129,14 @@ A definition minimally consists of the keyword :code:`fn`, an empty set of
parameters, and a body expression (:py:class:`~tvm.relay.expr.Expr`) parameters, and a body expression (:py:class:`~tvm.relay.expr.Expr`)
contained by curly braces. contained by curly braces.
.. code-block:: python .. code-block::
fn() { body } fn() { body }
A definition may contain any number of parameters. For example, a A definition may contain any number of parameters. For example, a
simple function that invokes the :code:`add` operator: simple function that invokes the :code:`add` operator:
.. code-block:: python .. code-block::
fn(%x, %y) { add(%x, %y) } fn(%x, %y) { add(%x, %y) }
...@@ -147,7 +147,7 @@ One may also annotate explicit types on functions. ...@@ -147,7 +147,7 @@ One may also annotate explicit types on functions.
For example, we can restrict the above function to only work For example, we can restrict the above function to only work
on certain types: on certain types:
.. code-block:: python .. code-block::
fn(%x : Tensor[(10, 10), float32], %y : Tensor[(10, 10), float32]) fn(%x : Tensor[(10, 10), float32], %y : Tensor[(10, 10), float32])
-> Tensor[(10, 10), float32] { -> Tensor[(10, 10), float32] {
...@@ -166,7 +166,7 @@ parameters and return type based on the function body and call sites. ...@@ -166,7 +166,7 @@ parameters and return type based on the function body and call sites.
A recursive function expression can be defined using a :code:`let` binding, A recursive function expression can be defined using a :code:`let` binding,
as here: as here:
.. code-block:: python .. code-block::
let %fact = fn(%x : Tensor[(10, 10), float32]) -> Tensor[(10, 10), float32] { let %fact = fn(%x : Tensor[(10, 10), float32]) -> Tensor[(10, 10), float32] {
if (%x == Constant(0, (10, 10), float32)) { if (%x == Constant(0, (10, 10), float32)) {
...@@ -189,7 +189,7 @@ For example, in the below example, the final result will be ...@@ -189,7 +189,7 @@ For example, in the below example, the final result will be
a tensor of zero values because the closure for :code:`%f` stores the value of a tensor of zero values because the closure for :code:`%f` stores the value of
:code:`%x` at the pointer where :code:`%f` was defined. :code:`%x` at the pointer where :code:`%f` was defined.
.. code-block:: python .. code-block::
let %g = fn() { let %g = fn() {
let %x = Constant(0, (10, 10), float32); let %x = Constant(0, (10, 10), float32);
...@@ -222,7 +222,7 @@ see :ref:`the documentation on type parameters <type-parameter>`. ...@@ -222,7 +222,7 @@ see :ref:`the documentation on type parameters <type-parameter>`.
For example, one can define a polymorphic identity function for For example, one can define a polymorphic identity function for
any Relay type as follows: any Relay type as follows:
.. code-block:: python .. code-block::
fn<t : Type>(%x : t) -> t { fn<t : Type>(%x : t) -> t {
%x %x
...@@ -231,7 +231,7 @@ any Relay type as follows: ...@@ -231,7 +231,7 @@ any Relay type as follows:
The below definition is also polymorphic, but restricts its The below definition is also polymorphic, but restricts its
arguments to tensor types: arguments to tensor types:
.. code-block:: python .. code-block::
fn<s : Shape, bt : BaseType>(%x : Tensor[s, bt]) { fn<s : Shape, bt : BaseType>(%x : Tensor[s, bt]) {
%x %x
...@@ -244,7 +244,7 @@ Notice that the return type is omitted and will be inferred. ...@@ -244,7 +244,7 @@ Notice that the return type is omitted and will be inferred.
A function may also be subject to one or more type relations, such as in A function may also be subject to one or more type relations, such as in
the following: the following:
.. code-block:: python .. code-block::
fn(%x, %y) where Broadcast { add(%x, %y) } fn(%x, %y) where Broadcast { add(%x, %y) }
...@@ -347,7 +347,7 @@ or global functions) and Relay operators. ...@@ -347,7 +347,7 @@ or global functions) and Relay operators.
The syntax of calls follows that used in C-like languages, demonstrated in the The syntax of calls follows that used in C-like languages, demonstrated in the
example below: example below:
.. code-block:: python .. code-block::
let %c = 1; let %c = 1;
let %f = fn(%x : Tensor[(), float32], %y : Tensor[(), float32]) { %x + %y + %c }; let %f = fn(%x : Tensor[(), float32], %y : Tensor[(), float32]) { %x + %y + %c };
...@@ -370,7 +370,7 @@ type checking. If a function is type-polymorphic and type arguments are not ...@@ -370,7 +370,7 @@ type checking. If a function is type-polymorphic and type arguments are not
given, type inference will attempt to infer type arguments if possible. given, type inference will attempt to infer type arguments if possible.
The following code gives examples of explicit and inferred type arguments: The following code gives examples of explicit and inferred type arguments:
.. code-block:: python .. code-block::
// %f : fn<a : Type, b : Type, c : Type>(a, b) -> c // %f : fn<a : Type, b : Type, c : Type>(a, b) -> c
let %x1 = %f<Tensor[(), bool], Tensor[(), bool], Tensor[(), bool)]>(True, False); let %x1 = %f<Tensor[(), bool], Tensor[(), bool], Tensor[(), bool)]>(True, False);
...@@ -390,7 +390,7 @@ and has the :code:`Broadcast` relation, then there are many different ...@@ -390,7 +390,7 @@ and has the :code:`Broadcast` relation, then there are many different
shapes that the arguments in the below call could have that would satisfy shapes that the arguments in the below call could have that would satisfy
the type annotation: the type annotation:
.. code-block:: python .. code-block::
let %x : Tensor[(100, 100, 100), float32] = %f(%a, %b); let %x : Tensor[(100, 100, 100), float32] = %f(%a, %b);
%x %x
...@@ -416,7 +416,7 @@ but have syntactic sugar in the text format to enter their definitions into the ...@@ -416,7 +416,7 @@ but have syntactic sugar in the text format to enter their definitions into the
a global function definition includes a global identifier and is allowed to recursively refer to a global function definition includes a global identifier and is allowed to recursively refer to
that identifier in the body, as in the following example: that identifier in the body, as in the following example:
.. code-block:: python .. code-block::
def @ackermann(%m : Tensor[(), int32], %n : Tensor[(), int32]) -> Tensor[(), int32] { def @ackermann(%m : Tensor[(), int32], %n : Tensor[(), int32]) -> Tensor[(), int32] {
if (%m == 0) { if (%m == 0) {
...@@ -459,7 +459,7 @@ The tuple node builds a finite (that is, of statically known size) sequence of h ...@@ -459,7 +459,7 @@ The tuple node builds a finite (that is, of statically known size) sequence of h
These tuples match Python's closely, and their fixed length allows for efficient projection of their These tuples match Python's closely, and their fixed length allows for efficient projection of their
members. members.
.. code-block:: python .. code-block::
fn(%a : Tensor[(10, 10), float32], %b : float32, %c : Tensor[(100, 100), float32]) { fn(%a : Tensor[(10, 10), float32], %b : float32, %c : Tensor[(100, 100), float32]) {
let %tup = (%a, %b); // type: (Tensor[(10, 10), float32], float32) let %tup = (%a, %b); // type: (Tensor[(10, 10), float32], float32)
...@@ -476,7 +476,7 @@ particular member of the tuple. Projections are 0-indexed. ...@@ -476,7 +476,7 @@ particular member of the tuple. Projections are 0-indexed.
For example, the below projection evaluates to :code:`%b`: For example, the below projection evaluates to :code:`%b`:
.. code-block:: python .. code-block::
(%a, %b, %c).1 (%a, %b, %c).1
...@@ -505,7 +505,7 @@ after evaluating the bindings it depends on. For example, in the ...@@ -505,7 +505,7 @@ after evaluating the bindings it depends on. For example, in the
following example the entire expression evaluates to a tensor following example the entire expression evaluates to a tensor
of shape :code:`(10, 10)` where all elements are 2: of shape :code:`(10, 10)` where all elements are 2:
.. code-block:: python .. code-block::
let %x : Tensor[(10, 10), float32] = Constant(1, (10, 10), float32); let %x : Tensor[(10, 10), float32] = Constant(1, (10, 10), float32);
%x + %x %x + %x
...@@ -518,7 +518,7 @@ For example, the first and second :code:`let` bindings below ...@@ -518,7 +518,7 @@ For example, the first and second :code:`let` bindings below
may be evaluated in either order because neither has a dataflow may be evaluated in either order because neither has a dataflow
dependency on the other: dependency on the other:
.. code-block:: python .. code-block::
let %x = %a + %b; let %x = %a + %b;
let %y = %c + %d; let %y = %c + %d;
...@@ -549,7 +549,7 @@ of this nuance). ...@@ -549,7 +549,7 @@ of this nuance).
In Relay's text format, a graph binding can be written as below (note the lack of a In Relay's text format, a graph binding can be written as below (note the lack of a
:code:`let` keyword and a semicolon): :code:`let` keyword and a semicolon):
.. code-block:: python .. code-block::
%1 = %a + %b %1 = %a + %b
%2 = %1 + %1 %2 = %1 + %1
...@@ -561,7 +561,7 @@ Python front-end by setting *Python variables* equal to the corresponding Relay ...@@ -561,7 +561,7 @@ Python front-end by setting *Python variables* equal to the corresponding Relay
using the variables repeatedly, as below (a C++ program using the corresponding API bindings using the variables repeatedly, as below (a C++ program using the corresponding API bindings
could accomplish the same thing): could accomplish the same thing):
.. code-block:: python .. code-block::
sum1 = relay.add(a, b) sum1 = relay.add(a, b)
sum2 = relay.add(sum1, sum1) sum2 = relay.add(sum1, sum1)
...@@ -581,7 +581,7 @@ Relay has a simple if-then-else expression that allows programs to branch ...@@ -581,7 +581,7 @@ Relay has a simple if-then-else expression that allows programs to branch
on a single value of type :code:`bool`, i.e., a zero-rank on a single value of type :code:`bool`, i.e., a zero-rank
tensor of booleans (:code:`Tensor[(), bool]`). tensor of booleans (:code:`Tensor[(), bool]`).
.. code-block:: python .. code-block::
if (%t == %u) { if (%t == %u) {
%t %t
...@@ -626,7 +626,7 @@ executed; the clause expression is evaluated and returned. ...@@ -626,7 +626,7 @@ executed; the clause expression is evaluated and returned.
For example, suppose we have an ADT for natural numbers: For example, suppose we have an ADT for natural numbers:
.. code-block:: python .. code-block::
data Nat { data Nat {
Z : () -> Nat # zero Z : () -> Nat # zero
...@@ -635,7 +635,7 @@ For example, suppose we have an ADT for natural numbers: ...@@ -635,7 +635,7 @@ For example, suppose we have an ADT for natural numbers:
Then the following function subtracts one from a passed nat: Then the following function subtracts one from a passed nat:
.. code-block:: python .. code-block::
fn(%v: Nat[]) -> Nat[] { fn(%v: Nat[]) -> Nat[] {
match(%v) { match(%v) {
...@@ -647,7 +647,7 @@ Then the following function subtracts one from a passed nat: ...@@ -647,7 +647,7 @@ Then the following function subtracts one from a passed nat:
The following function subtracts two from its argument if it is at least The following function subtracts two from its argument if it is at least
two and returns the argument otherwise, using a nested constructor pattern: two and returns the argument otherwise, using a nested constructor pattern:
.. code-block:: python .. code-block::
fn(%v : Nat[]) -> Nat[] { fn(%v : Nat[]) -> Nat[] {
match(%v) { match(%v) {
...@@ -661,7 +661,7 @@ As aforementioned, the ordering of match clauses is relevant. ...@@ -661,7 +661,7 @@ As aforementioned, the ordering of match clauses is relevant.
In the below example, the first clause will always match so In the below example, the first clause will always match so
those below it can never run: those below it can never run:
.. code-block:: python .. code-block::
fn(%v : Nat[]) -> Nat[] { fn(%v : Nat[]) -> Nat[] {
match(%v) { match(%v) {
......
...@@ -80,7 +80,7 @@ running a program. ...@@ -80,7 +80,7 @@ running a program.
For example, here is a simple concrete tensor type corresponding to a 10-by-10 tensor of 32-bit floats: For example, here is a simple concrete tensor type corresponding to a 10-by-10 tensor of 32-bit floats:
.. code-block:: python .. code-block::
Tensor[(10, 10), float32] Tensor[(10, 10), float32]
...@@ -101,7 +101,7 @@ For example, in the below code, :code:`%t` is of type ...@@ -101,7 +101,7 @@ For example, in the below code, :code:`%t` is of type
:code:`(Tensor[(), bool], Tensor[(10, 10), float32])` :code:`(Tensor[(), bool], Tensor[(10, 10), float32])`
and :code:`%c` is of type :code:`Tensor[(10, 10), float32]`. and :code:`%c` is of type :code:`Tensor[(10, 10), float32]`.
.. code-block:: python .. code-block::
let %t = (False, Constant(1, (10, 10), float32)); let %t = (False, Constant(1, (10, 10), float32));
let %c = %t.1; let %c = %t.1;
...@@ -135,7 +135,7 @@ Like normal parameters, concrete arguments must be given for type parameters at ...@@ -135,7 +135,7 @@ Like normal parameters, concrete arguments must be given for type parameters at
For example, :code:`s` below is a type parameter of kind :code:`Shape` and it will For example, :code:`s` below is a type parameter of kind :code:`Shape` and it will
be substituted with :code:`(10, 10)` at the call site below: be substituted with :code:`(10, 10)` at the call site below:
.. code-block:: python .. code-block::
def @plus<s : Shape>(%t1 : Tensor[s, float32], %t2 : Tensor[s, float32]) { def @plus<s : Shape>(%t1 : Tensor[s, float32], %t2 : Tensor[s, float32]) {
add(%t1, %t2) add(%t1, %t2)
...@@ -212,7 +212,7 @@ and the return type. For example, we can define the relation for :code:`flatten` ...@@ -212,7 +212,7 @@ and the return type. For example, we can define the relation for :code:`flatten`
If we have a relation like :code:`Broadcast` it becomes possible If we have a relation like :code:`Broadcast` it becomes possible
to type operators like :code:`add`: to type operators like :code:`add`:
.. code-block:: python .. code-block::
add : fn<t1 : Type, t2 : Type, t3 : Type>(t1, t2) -> t3 add : fn<t1 : Type, t2 : Type, t3 : Type>(t1, t2) -> t3
where Broadcast where Broadcast
...@@ -359,7 +359,7 @@ This subsection uses the simple list ADT (included as a default ...@@ -359,7 +359,7 @@ This subsection uses the simple list ADT (included as a default
ADT in Relay) to illustrate the constructs described in the previous ADT in Relay) to illustrate the constructs described in the previous
sections. Its definition is as follows: sections. Its definition is as follows:
.. code-block:: python .. code-block::
data List<a> { data List<a> {
Nil : () -> List Nil : () -> List
...@@ -377,7 +377,7 @@ variable :code:`List` in the constructor definition. ...@@ -377,7 +377,7 @@ variable :code:`List` in the constructor definition.
Below two instances of lists with their types given, using type calls: Below two instances of lists with their types given, using type calls:
.. code-block:: python .. code-block::
Cons(1, Cons(2, Nil())) # List[Tensor[(), int32]] Cons(1, Cons(2, Nil())) # List[Tensor[(), int32]]
Cons((1, 1), Cons((2, 2), Nil())) # List[(Tensor[(), int32], Tensor[(), int32])] Cons((1, 1), Cons((2, 2), Nil())) # List[(Tensor[(), int32], Tensor[(), int32])]
...@@ -390,7 +390,7 @@ be specified.) ...@@ -390,7 +390,7 @@ be specified.)
Here are two lists that are rejected by the type system because Here are two lists that are rejected by the type system because
the type parameters do not match: the type parameters do not match:
.. code-block:: python .. code-block::
# attempting to put an integer on a list of int * int tuples # attempting to put an integer on a list of int * int tuples
Cons(1, Cons((1, 1), Nil())) Cons(1, Cons((1, 1), Nil()))
......
...@@ -36,7 +36,7 @@ echo "PreCheck sphinx doc generation WARNINGS.." ...@@ -36,7 +36,7 @@ echo "PreCheck sphinx doc generation WARNINGS.."
cd docs cd docs
TVM_TUTORIAL_EXEC_PATTERN=none make html 2>/tmp/$$.log.txt TVM_TUTORIAL_EXEC_PATTERN=none make html 2>/tmp/$$.log.txt
grep -v -E "__mro__|RemovedInSphinx|UserWarning|FutureWarning" < /tmp/$$.log.txt > /tmp/$$.logclean.txt || true grep -v -E "__mro__|RemovedInSphinx|UserWarning|FutureWarning|Keras" < /tmp/$$.log.txt > /tmp/$$.logclean.txt || true
echo "---------Sphinx Log----------" echo "---------Sphinx Log----------"
cat /tmp/$$.logclean.txt cat /tmp/$$.logclean.txt
echo "-----------------------------" echo "-----------------------------"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment