Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SYCL][CUDA][Matrix] Initial Tensorcore matrix ext impl #4696

Merged
merged 7 commits into from
Nov 8, 2021

Conversation

JackAKirk
Copy link
Contributor

@JackAKirk JackAKirk commented Oct 4, 2021

Initial Implementation based on the new matrix extension supporting Nvidia Tensorcore, #4695, that is adapted from the AMX matrix extension.
Only double data type matrix elements are initially supported.

Signed-off-by: jack.kirk [email protected]

Only double data type matrix elements are initially supported.
Adaptation of the AMX matrix extension to also support Nvidia tensorcore hardware.

Signed-off-by: jack.kirk <[email protected]>
@pvchupin pvchupin requested a review from dkhaldi October 4, 2021 18:55
Copy link
Contributor

@dkhaldi dkhaldi left a comment

Choose a reason for hiding this comment

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

Thank you for doing this work.
This is a nice work and shows how the joint_matrix interface can apply to other TPUs like the Nvidia one. I posted some comments mostly about the interface.

sycl/include/sycl/ext/oneapi/matrix/matrix-tensorcore.hpp Outdated Show resolved Hide resolved
namespace intel {
namespace experimental::matrix {

enum class matrix_type { a, b, accumulator };
Copy link
Contributor

Choose a reason for hiding this comment

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

While we don't have this right now, this will be needed for future support.
So this is a good addition to the interface, I would suggest changing the name though to matrix_use rather than type.
Also, please take a look at the query interface in static-query.hpp. It provides a nice way to bypass all these extra arguments including the sizes (see example in https://github.com/intel/llvm/blob/sycl/sycl/test/matrix/query.cpp)
You just need to say:
using myparams = tpu_params<tpu::nvidia, int8_t, int8_t, int>;
the matrices can be created as follows:
myparams::joint_matrix_a<sub_group> sub_a(sg);
myparams::joint_matrix_b<sub_group> sub_b(sg);
myparams::joint_matrix_c<sub_group> sub_c(sg);

As you can see the sizes are constructed underneath. The matrix_use is specified in the type alias.

Copy link
Contributor Author

@JackAKirk JackAKirk Oct 5, 2021

Choose a reason for hiding this comment

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

Thanks, I think that the query which misses matrix size parameters will be useful for the tensorcore case, both as a user query to inform which matrix sizes are available for the given matrix_type (using the definition of matrix_type in static_query.hpp which basically corresponds to matrix::precision that was described in the tensorcore matrix proposal) and also to potentially reduce the number of parameters necessary in the group functions in the cases where a single matrix_type corresponds to a single matrix size (although there are only a small number of cases where this is valid for cuda - In the majority of cases all template parameters will be needed to uniquely specify the correct joint_matrix: see https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#warp-level-matrix-shape). Since the tensorcore case does not support a continuous range of integers for the matrix sizes, the variables such as max_msize, max_nsize, max_ksize won't be appropriate for the cuda case, but we could e.g. make an alternative implementation for cuda which can report to the user the set of available matrix sizes (most commonly there are two or three per matrix_type) for each 'matrix_type'.

Copy link
Contributor

Choose a reason for hiding this comment

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

Since the tensorcore case does not support a continuous range of integers for the matrix sizes, the variables such as max_msize, max_nsize, max_ksize won't be appropriate for the cuda case

the max_msize/nsize/ksize are only appropriate for AMX.
the DPAS GPU implementation also supports a discrete range of values. That would be msize/nsize/ksize members of 'combination' type. Please refer to https://github.com/intel/llvm/blob/sycl/sycl/include/sycl/ext/oneapi/matrix/static-query.hpp#L297 on how we filled out the combinations for DPAS.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see, thanks.

@@ -25,3 +25,6 @@
#include <sycl/ext/oneapi/matrix/matrix-jit.hpp>
#include <sycl/ext/oneapi/matrix/static-query.hpp>
#endif
#if (SYCL_EXT_ONEAPI_MATRIX == 3)
Copy link
Contributor

Choose a reason for hiding this comment

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

This implementation can also benefit from the static query we have as well. Besides that the query can give the user information about what the implementation support, it can also construct the matrices and make the sizes optional for the user.

We should probably add this to matrix-jit.hpp and fork to using the AOT tensorcore implementation based on some option (AOT for tensorcore).
I am asking this because we should have one place that has the interface to make maintaining the code easy but also, since this interface is experimental, we expect it will be changed (like the use argument you introduce). We should make the interface in one place so we only have to modify it in only one place.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you think that there should be a single header for all of the definitions of joint_matrix, joint_matrix_load, joint_matrix_store, joint_matrix_mad, and then backend dependent specializations of these functions can be in separate files?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, if you can use the same things as in matrix/matrix-jit.hpp like matrix_layout and not redefine them, that would be better.
For the things that are different like the definition of joint_matrix type, joint_matrix_load/store/mad because of "use" argument, can you add the use-definitions in matrix-jit.hpp (under the new test macro = 3)

As you know, we are planning on adding the new "use" argument for AMX and DPAS as well. Once we do that, there will be one definition of joint_matrix type/joint_matrix_load/store/mad.

If you make this change now, later, there will be one place for us to change (remove the old joint_matrix,load,store,mad that do not have "use" argument). And we won't need to touch the tensorcores specific specifications that will be in a different file.

Also, when this convergence happens, there will be no need for the feature test macro. Since this is an experimental interface, we don't need to keep track of "old" versions of the interface. We will remove AOT AMX (SYCL_EXT_ONEAPI_MATRIX=1), we only keep matrix-jit.hpp that enables DPAS, AMX and tensorecores.

Copy link
Contributor Author

@JackAKirk JackAKirk Oct 19, 2021

Choose a reason for hiding this comment

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

matrix_layout has an identical definition as in matrix-jit.hpp.

For the things that are different like the definition of joint_matrix type, joint_matrix_load/store/mad because of "use" argument, can you add the use-definitions in matrix-jit.hpp (under the new test macro = 3)

As you know, we are planning on adding the new "use" argument for AMX and DPAS as well. Once we do that, there will be one definition of joint_matrix type/joint_matrix_load/store/mad.

I'm not sure what you are asking me to do here? : if I add the definitions of joint_matrix_* used in matrix-tensorcore.hpp into matrix-jit.hpp they will be a redeclaration of the intel specific functions already defined in matrix-jit.hpp that do not use the matrix_use template parameter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @dkhaldi , We would like to get this merged. Could you clarify what you would like me to change? Thanks.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry for late reply, I was thinking you can have these defined under the new test macro = 3 in the same file so they don't get redefined.
However, I think it will be best if we merge these as separate files. Once we add the use argument, we can reiterate on this to merge both files. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK sure, I think that keeping them separate is a good idea for now.

sycl/test/matrix/matrix-cuda.cpp Outdated Show resolved Hide resolved
sycl/include/sycl/ext/oneapi/matrix/matrix-tensorcore.hpp Outdated Show resolved Hide resolved
Switched namespace intel with oneapi.
Moved Group template parameter to end of parameter list in joint_matrix.
Removed unnecessary template parameter Group from impl functions.

Signed-off-by: jack.kirk <[email protected]>
@bader bader requested a review from romanovvlad October 11, 2021 10:59
romanovvlad
romanovvlad previously approved these changes Oct 12, 2021
@@ -0,0 +1,99 @@
// RUN: %clangxx -fsycl-device-only -fsycl-targets=nvptx64-nvidia-cuda -Xsycl-target-backend --cuda-gpu-arch=sm_80 -DSYCL_EXT_ONEAPI_MATRIX=3 -S -Xclang -emit-llvm %s -o -| FileCheck %s

#include <CL/sycl.hpp>
Copy link
Contributor

Choose a reason for hiding this comment

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

rename this file to matrix-nvptx-double-test.cpp to match the name in other matrix tests

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, I've renamed the test.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why is the test under test/check_device_code rather than test/matrix?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This test is a device code only test. I thought that we were meant to put runtime tests like those in https://github.com/intel/llvm/tree/sycl/sycl/test/matrix in https://github.com/intel/llvm-test-suite/tree/intel/SYCL/Matrix from now on?

Copy link
Contributor

Choose a reason for hiding this comment

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

@JackAKirk I see now, thanks.
@romanovvlad, is check_device_code/ the right folder for matrix-nvptx-double-test.cpp or should it stay under matrix/?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the test should be somewhere in check_device_code. We may introduce a matrix subdir if it makes sense so the final location is sycl/test/check_device_code/matrix/matrix-builtins-nvptx.cpp.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I've moved the test to sycl/test/check_device_code/matrix

matrix_layout::packed -> packed_a, packed_b

Signed-off-by: jack.kirk <[email protected]>
dkhaldi
dkhaldi previously approved these changes Nov 2, 2021
Copy link
Contributor

@dkhaldi dkhaldi left a comment

Choose a reason for hiding this comment

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

LGTM

@JackAKirk
Copy link
Contributor Author

JackAKirk commented Nov 3, 2021

The test fails due to:

cannot find libdevice for sm_80

I ran this test on sm_61 with the 11.4 CUDA driver and it passed. Does your CI have an up to date CUDA driver that supports sm_80?

@JackAKirk
Copy link
Contributor Author

The test fails due to:

cannot find libdevice for sm_80

I ran this test on sm_61 with the 11.4 CUDA driver and it passed. Does your CI have an up to date CUDA driver that supports sm_80?

Sorry I think this happened because I had missed // REQUIRES: gpu, cuda. Should be fine now.

@JackAKirk
Copy link
Contributor Author

The test fails due to:
cannot find libdevice for sm_80
I ran this test on sm_61 with the 11.4 CUDA driver and it passed. Does your CI have an up to date CUDA driver that supports sm_80?

Sorry I think this happened because I had missed // REQUIRES: gpu, cuda. Should be fine now.

@romanovvlad can we run the tests again? Thanks

@romanovvlad romanovvlad merged commit 711ba58 into intel:sycl Nov 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants