diff options
author | CNugteren <web@cedricnugteren.nl> | 2015-09-18 17:46:41 +0200 |
---|---|---|
committer | CNugteren <web@cedricnugteren.nl> | 2015-09-18 17:46:41 +0200 |
commit | 93dddda63e4345961a779ee125d748c1eeef4769 (patch) | |
tree | ecb99fedbe765152259dec595833431b703e2fb3 /src/kernels | |
parent | 4507ba4997cd546418eae0972c018073ac7b36aa (diff) |
Improved the organization and performance of level 2 routines
Diffstat (limited to 'src/kernels')
-rw-r--r-- | src/kernels/level2/xgemv.opencl | 80 | ||||
-rw-r--r-- | src/kernels/matrix_transforms/gbgemt.opencl | 60 | ||||
-rw-r--r-- | src/kernels/matrix_transforms/transforms.opencl | 40 |
3 files changed, 61 insertions, 119 deletions
diff --git a/src/kernels/level2/xgemv.opencl b/src/kernels/level2/xgemv.opencl index 1e12dd78..0ecfc960 100644 --- a/src/kernels/level2/xgemv.opencl +++ b/src/kernels/level2/xgemv.opencl @@ -79,22 +79,61 @@ R"( #endif // ================================================================================================= -// Defines how to load the input matrix in the regular case -// Loads a scalar input value +// Defines how to load the input matrix in the non-vectorized case inline real LoadMatrixA(const __global real* restrict agm, const int x, const int y, - const int a_ld, const int a_offset) { - return agm[x + a_ld*y + a_offset]; + const int a_ld, const int a_offset, const int reversed, + const int kl, const int ku) { + real result; + + // For symmetric matrices + #if defined(ROUTINE_SYMV) + if ((reversed == 0 && y <= x) || (reversed == 1 && x <= y)) { + result = agm[y*a_ld + x + a_offset]; + } + else { + result = agm[x*a_ld + y + a_offset]; + } + + // For hermitian matrices + #elif defined(ROUTINE_HEMV) + if ((reversed == 0 && y <= x) || (reversed == 1 && x <= y)) { + result = agm[y*a_ld + x + a_offset]; + if (x == y) { result.y = ZERO; } + } + else { + result = agm[x*a_ld + y + a_offset]; + COMPLEX_CONJUGATE(result); + } + + // For banded matrices + #elif defined(ROUTINE_GBMV) + const int k = ku-y+x; + if (x >= y-ku && x < y+kl+1) { + result = agm[a_ld*y + k + a_offset]; + } + else { + SetToZero(result); + } + + // For general matrices + #else + result = agm[a_ld*y + x + a_offset]; + #endif + + return result; } + // Loads a vector input value (1/2) inline realVF LoadMatrixAVF(const __global realVF* restrict agm, const int x, const int y, const int a_ld) { - return agm[x + a_ld*y]; + return agm[a_ld*y + x]; } + // Loads a vector input value (2/2): as before, but different data-type inline realVFR LoadMatrixAVFR(const __global realVFR* restrict agm, const int x, const int y, const int a_ld) { - return agm[x + a_ld*y]; + return agm[a_ld*y + x]; } // ================================================================================================= @@ -106,7 +145,8 @@ __kernel void Xgemv(const int m, const int n, const real alpha, const real beta, const __global real* restrict agm, const int a_offset, const int a_ld, const __global real* restrict xgm, const int x_offset, const int x_inc, __global real* ygm, const int y_offset, const int y_inc, - const int do_conjugate) { + const int do_conjugate, const int reversed, + const int kl, const int ku) { // Local memory for the vector X __local real xlm[WGS1]; @@ -141,20 +181,20 @@ __kernel void Xgemv(const int m, const int n, const real alpha, const real beta, // The multiply-add function for the main part (divisable by WGS1) if (a_rotated == 0) { // Not rotated #pragma unroll - for (int kl=0; kl<WGS1; ++kl) { - const int k = kwg + kl; - real value = LoadMatrixA(agm, gid, k, a_ld, a_offset); + for (int kloop=0; kloop<WGS1; ++kloop) { + const int k = kwg + kloop; + real value = LoadMatrixA(agm, gid, k, a_ld, a_offset, reversed, kl, ku); if (do_conjugate == 1) { COMPLEX_CONJUGATE(value); } - MultiplyAdd(acc[w], xlm[kl], value); + MultiplyAdd(acc[w], xlm[kloop], value); } } else { // Transposed #pragma unroll - for (int kl=0; kl<WGS1; ++kl) { - const int k = kwg + kl; - real value = LoadMatrixA(agm, k, gid, a_ld, a_offset); + for (int kloop=0; kloop<WGS1; ++kloop) { + const int k = kwg + kloop; + real value = LoadMatrixA(agm, k, gid, a_ld, a_offset, reversed, kl, ku); if (do_conjugate == 1) { COMPLEX_CONJUGATE(value); } - MultiplyAdd(acc[w], xlm[kl], value); + MultiplyAdd(acc[w], xlm[kloop], value); } } } @@ -174,7 +214,7 @@ __kernel void Xgemv(const int m, const int n, const real alpha, const real beta, if (a_rotated == 0) { // Not rotated #pragma unroll for (int k=n_floor; k<n; ++k) { - real value = LoadMatrixA(agm, gid, k, a_ld, a_offset); + real value = LoadMatrixA(agm, gid, k, a_ld, a_offset, reversed, kl, ku); if (do_conjugate == 1) { COMPLEX_CONJUGATE(value); } MultiplyAdd(acc[w], xgm[k*x_inc + x_offset], value); } @@ -182,7 +222,7 @@ __kernel void Xgemv(const int m, const int n, const real alpha, const real beta, else { // Transposed #pragma unroll for (int k=n_floor; k<n; ++k) { - real value = LoadMatrixA(agm, k, gid, a_ld, a_offset); + real value = LoadMatrixA(agm, k, gid, a_ld, a_offset, reversed, kl, ku); if (do_conjugate == 1) { COMPLEX_CONJUGATE(value); } MultiplyAdd(acc[w], xgm[k*x_inc + x_offset], value); } @@ -209,7 +249,8 @@ __kernel void XgemvFast(const int m, const int n, const real alpha, const real b const __global realVF* restrict agm, const int a_offset, const int a_ld, const __global real* restrict xgm, const int x_offset, const int x_inc, __global real* ygm, const int y_offset, const int y_inc, - const int do_conjugate) { + const int do_conjugate, const int reversed, + const int kl, const int ku) { // Local memory for the vector X __local real xlm[WGS2]; @@ -305,7 +346,8 @@ __kernel void XgemvFastRot(const int m, const int n, const real alpha, const rea const __global realVFR* restrict agm, const int a_offset, const int a_ld, const __global real* restrict xgm, const int x_offset, const int x_inc, __global real* ygm, const int y_offset, const int y_inc, - const int do_conjugate) { + const int do_conjugate, const int reversed, + const int kl, const int ku) { // Local memory for the vector X __local real xlm[WGS3]; diff --git a/src/kernels/matrix_transforms/gbgemt.opencl b/src/kernels/matrix_transforms/gbgemt.opencl deleted file mode 100644 index e46e3a59..00000000 --- a/src/kernels/matrix_transforms/gbgemt.opencl +++ /dev/null @@ -1,60 +0,0 @@ - -// ================================================================================================= -// This file is part of the CLBlast project. The project is licensed under Apache Version 2.0. This -// project loosely follows the Google C++ styleguide and uses a tab-size of two spaces and a max- -// width of 100 characters per line. -// -// Author(s): -// Cedric Nugteren <www.cedricnugteren.nl> -// -// This file contains the general banded (gb) to general (ge) matrix transforms. -// -// This kernel uses the matrix-transforms common tuning parameters. -// -// ================================================================================================= - -// Enables loading of this file using the C++ pre-processor's #include (C++11 standard raw string -// literal). Comment-out this line for syntax-highlighting when developing. -R"( - -// ================================================================================================= -#if defined(ROUTINE_GBMV) - -// Kernel to transform a general banded matrix into a general matrix -__attribute__((reqd_work_group_size(PAD_DIMX, PAD_DIMY, 1))) -__kernel void GeneralBandedToGeneral(const int src_one, const int src_two, - const int src_ld, const int src_offset, - __global const real* restrict src, - const int dest_one, const int dest_two, - const int dest_ld, const int dest_offset, - __global real* dest, - const int layout, - const int kl, const int ku) { - - // Loops over the work per thread in both dimensions - #pragma unroll - for (int w_one=0; w_one<PAD_WPTX; ++w_one) { - const int id_one = (get_group_id(0)*PAD_WPTX + w_one) * PAD_DIMX + get_local_id(0); - #pragma unroll - for (int w_two=0; w_two<PAD_WPTY; ++w_two) { - const int id_two = (get_group_id(1)*PAD_WPTY + w_two) * PAD_DIMY + get_local_id(1); - if (id_two < dest_two && id_one < dest_one) { - real result; - SetToZero(result); - const int k = ku - id_two + id_one; - if ((id_one >= id_two - ku) && (id_one < id_two + kl + 1)) { - result = src[id_two*src_ld + k + src_offset]; - } - dest[id_two*dest_ld + id_one + dest_offset] = result; - } - } - } -} - -#endif -// ================================================================================================= - -// End of the C++11 raw string literal -)" - -// ================================================================================================= diff --git a/src/kernels/matrix_transforms/transforms.opencl b/src/kernels/matrix_transforms/transforms.opencl deleted file mode 100644 index 01889a13..00000000 --- a/src/kernels/matrix_transforms/transforms.opencl +++ /dev/null @@ -1,40 +0,0 @@ - -// ================================================================================================= -// This file is part of the CLBlast project. The project is licensed under Apache Version 2.0. This -// project loosely follows the Google C++ styleguide and uses a tab-size of two spaces and a max- -// width of 100 characters per line. -// -// Author(s): -// Cedric Nugteren <www.cedricnugteren.nl> -// -// This file contains the common functions and parameters specific for matrix-transform kernels. -// -// ================================================================================================= - -// Enables loading of this file using the C++ pre-processor's #include (C++11 standard raw string -// literal). Comment-out this line for syntax-highlighting when developing. -R"( - -// ================================================================================================= - -// Parameters set by the tuner or by the database. Here they are given a basic default value in case -// this kernel file is used outside of the CLBlast library. -#ifndef PAD_DIMX - #define PAD_DIMX 8 // Local workgroup size in the first dimension (x) -#endif -#ifndef PAD_DIMY - #define PAD_DIMY 8 // Local workgroup size in the second dimension (y) -#endif -#ifndef PAD_WPTX - #define PAD_WPTX 1 // Work per thread in the first dimension (x) -#endif -#ifndef PAD_WPTY - #define PAD_WPTY 1 // Work per thread in the second dimension (y) -#endif - -// ================================================================================================= - -// End of the C++11 raw string literal -)" - -// ================================================================================================= |