Skip to content

[Tutorial] tutorial for tensorize - #1774

Merged
tqchen merged 3 commits into
apache:masterfrom
yzhliu:tutorial-tensorize
Oct 4, 2018
Merged

tqchen merged 3 commits into
apache:masterfrom
yzhliu:tutorial-tensorize

Conversation

@yzhliu

@yzhliu yzhliu commented Sep 26, 2018

Copy link
Copy Markdown
Member

@anijain2305 anijain2305 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @yzhliu for this tutorial. This is very helpful. I had so many questions when I was trying to use tensorize the first time. This tutorial is answering many of those questions.

#
N, M, L = 1024, 512, 64
A = tvm.placeholder((N, L), name='A')
B = tvm.placeholder((M, L), name='B')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems matrix B is transposed here. If not, A should be NxL and B should be LxM.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's A * B^T, maybe define it more clearly beforehand? or it is better to do A * B?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a better definition will suffice here. I think it is necessary to have this here because it becomes easier later to map GEMV

B = tvm.placeholder((M, L), name='B')
k = tvm.reduce_axis((0, L), name='k')
C = tvm.compute((N, M), lambda i, j:
tvm.sum(A[i, k] * B[j, k], axis=k), name='C')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the matrix B is not supposed to be transposed, it will be B[k, j]

Comment thread tutorials/language/tensorize.py Outdated
=========
**Author**: `Yizhi Liu <https://github.com/yzhliu>`_

This is an introduction material on how to do tensorization in TVM.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do --> perform

Comment thread tutorials/language/tensorize.py Outdated
as well as extend TVM to support new hardware architectures.

In this tutorial, we will demonstrate the usage of tensorization.
Notice that the examples are more for showing the functionality,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rewrite suggestion - The purpose of this tutorial is to show the functionality and usage of tensorize instead of providing an efficient solution.

Comment thread tutorials/language/tensorize.py Outdated
######################################################################
# Schedule the Matmul
# -------------------
# Now suppose we had an accelerator supports matrix-vector multiplication (GEMV) as a hardware primitive,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rewrite suggestion - Now, suppose we have an accelerator that

Comment thread tutorials/language/tensorize.py Outdated
# Before scheduling the tensorization, we need to first define the intrinsic function for GEMV.
# It includes two parts, the first is computing definition of GEMV,
# TVM uses it to match the computing pattern in the original Matmul schedule.
# The second is the definition of how to execute GEMV on the device.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be more concrete to say the second portion is done in "intrin_func" if we are avoiding writing comments in the code.

# Here :code:`tvm.decl_tensor_intrin` declares how to execute the computation :code:`c.op`.
# Our implementation simply takes the inputs and outputs,
# converts them to pointers and emit an external function call.
# Note that tensorization requires user to specify :code:`offset_factor`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding the offset_factor description. It seems important but I was not able to fully understand the description. Maybe an example would be helpful here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah it is still not very clear given the description here. Actually offset_factor hasn't been used in current TVM for loading optimization, only CHECK(elem_offset % offset_factor == 0) is inserted into the codegen. I'm thinking about adding more details in the Buffer doc.

Comment thread tutorials/language/tensorize.py Outdated
b = np.random.uniform(size=get_const_tuple(B.shape)).astype(dtype)
c = tvm.nd.array(np.zeros(get_const_tuple(C.shape), dtype=dtype), ctx)
func(tvm.nd.array(a, ctx), tvm.nd.array(b, ctx), c)
np.testing.assert_array_almost_equal(c.asnumpy(), np.dot(a, b.T), decimal=2)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is numpy.testing.assert_allclose any better?

Comment thread tutorials/language/tensorize.py Outdated
cc.access_ptr("w"), aa.access_ptr("r"), bb.access_ptr("r"),
m, l, bb.strides[0]))
return ib.get()
return _instrin(0), _instrin(1), _instrin(2)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, I think we need more details here. We can rewrite the code to have 3 functions - reduce_reset, reduce_update and body. This will make things clearer. I think this is important for first-time users. I had the same questions when I was trying to use tensorize.

Comment thread tutorials/language/tensorize.py Outdated
b = np.random.uniform(size=get_const_tuple(B.shape)).astype(dtype)
c = tvm.nd.array(np.zeros(get_const_tuple(C.shape), dtype=dtype), ctx)
func(tvm.nd.array(a, ctx), tvm.nd.array(b, ctx), c)
np.testing.assert_array_almost_equal(c.asnumpy(), np.dot(a, b.T), decimal=2)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

allclose?

Comment thread python/tvm/ir_builder.py Outdated
ib = tvm.ir_builder.create()
x = ib.pointer("float32")
with ib.for_range(1, 10, name="i") as i:
with ib.for_range(0, 10, name="i") as i:

@ZihengJiang ZihengJiang Sep 26, 2018 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here is an i-1 in below expression

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my bad...

Comment thread tutorials/language/tensorize.py Outdated
@@ -0,0 +1,276 @@
"""
Use Tensorize to Leverage Hardware Intrinsics
=========

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

align the text and "===="

Comment thread tutorials/language/tensorize.py Outdated
# which can take arbitrary size of reduce axis, but another axis needs to be no larger than 16.
# Thus we break down the matmul loops to make the innermost loops a (16x64) GEMV.
#
s = tvm.create_schedule(C.op)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding another print of the IR here might be nice for comparison with the IR with the loops split.

Comment thread tutorials/language/tensorize.py Outdated
# - within the inner most two loops, the index :code:`i` is fixed,
# the access to the matrix :code:`A` only varies by :code:`k`,
# which makes the access pattern of :code:`A` a "vector".
# In order to leverage our "virtual" hardware's GEMV instruction,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use 'hypothetical hardware', if you're trying to emphasize this is for a imaginary backend.

Comment thread tutorials/language/tensorize.py Outdated
# Define GEMV Tensorization Intrinsic
# -----------------------------------
# Before scheduling the tensorization, we need to first define the intrinsic function for GEMV.
# It includes two parts, the first is computing definition of GEMV,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would reword to:
It includes two parts, the first is a compute definition of GEMV.

@tqchen tqchen added status: need update need update based on feedbacks and removed beginner-friendly labels Sep 29, 2018
@yzhliu

yzhliu commented Sep 30, 2018

Copy link
Copy Markdown
Member Author

Thanks @anijain2305 @ZihengJiang @merrymercy @cowanmeg Pls review again.

@tqchen

tqchen commented Oct 1, 2018

Copy link
Copy Markdown
Member

@anijain2305 anijain2305 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

#
N, M, L = 1024, 512, 64
A = tvm.placeholder((N, L), name='A')
B = tvm.placeholder((M, L), name='B')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a better definition will suffice here. I think it is necessary to have this here because it becomes easier later to map GEMV

@ZihengJiang ZihengJiang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other parts look good to me

Comment thread tutorials/language/tensorize.py Outdated
# For now :code:`bb.strides[0] == l`,
# but later we will see how they can differ with more complicated schedules.
#
# Note that we use :code:`tvm.var("ldw")` as the first stride dimension for :code:`B`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, I am curious whether 'ldw' has any meaning.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I change it to s1 for stride1 instead.

@tqchen

tqchen commented Oct 2, 2018

Copy link
Copy Markdown
Member

@yzhliu can you act on the final review comments?

@apache apache deleted a comment from ZihengJiang Oct 2, 2018
Comment thread tutorials/language/tensorize.py
@tqchen
tqchen merged commit 147f3ad into apache:master Oct 4, 2018
@tqchen

tqchen commented Oct 4, 2018

Copy link
Copy Markdown
Member

Thanks @yzhliu @cowanmeg @ZihengJiang @anijain2305 @merrymercy this is now merged!

@tqchen tqchen added status: accepted and removed status: need review status: need update need update based on feedbacks labels Oct 4, 2018
@yzhliu
yzhliu deleted the tutorial-tensorize branch November 5, 2018 07:12
FrozenGene pushed a commit to FrozenGene/tvm that referenced this pull request Dec 27, 2018
@zhenhuaw-me

zhenhuaw-me commented Feb 26, 2019 •

Copy link
Copy Markdown
Contributor

Hi, have we considered writing tutorial with jupyter notebook? I notice that most tutorials are interactive. By interactive I mean, read a document segment, run a code segment, check the result of that code segment, and go on. Jupyter notebook seems very good at this.

@yidawang

Copy link
Copy Markdown
Contributor

It is a Jupyter notebook. For this one, check out https://docs.tvm.ai/tutorials/language/tensorize.html#sphx-glr-tutorials-language-tensorize-py, go to the end of the page, you will see Download Jupyter notebook: tensorize.ipynb

@zhenhuaw-me

zhenhuaw-me commented Feb 26, 2019 via email

Copy link
Copy Markdown
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants