1 /* ************************************************************************
2 * Copyright 2013 Advanced Micro Devices, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 * ************************************************************************/
16
17
18 #include <matrix_dims.h>
19
20 static __inline bool
isRightSide(BlasFunctionID funcID,clblasSide side)21 isRightSide(BlasFunctionID funcID, clblasSide side)
22 {
23 return ((funcID == CLBLAS_TRMM || funcID == CLBLAS_TRSM) &&
24 side == clblasRight);
25 }
26
27 void VISIBILITY_HIDDEN
swapDimXY(SubproblemDim * dim)28 swapDimXY(SubproblemDim *dim)
29 {
30 size_t tmp;
31
32 tmp = dim->itemX;
33 dim->itemX = dim->itemY;
34 dim->itemY = tmp;
35 tmp = dim->x;
36 dim->x = dim->y;
37 dim->y = tmp;
38 }
39
40 size_t VISIBILITY_HIDDEN
matrBlockPitch(const SubproblemDim * dim,MatrixRole mrole,DataType dtype,clblasSide side)41 matrBlockPitch(
42 const SubproblemDim *dim,
43 MatrixRole mrole,
44 DataType dtype,
45 clblasSide side)
46 {
47 size_t tsize = dtypeSize(dtype);
48 size_t nfloats = tsize / sizeof(cl_float);
49 size_t rowLen = 0;
50
51 switch (mrole) {
52 case MATRIX_A:
53 case MATRIX_B:
54 rowLen = dim->bwidth;
55 break;
56 case MATRIX_C:
57 rowLen = (side == clblasLeft) ? dim->x : dim->y;
58 break;
59 default:
60 break;
61 }
62
63 rowLen = fl4RowWidth(rowLen, tsize) * FLOAT4_VECLEN / nfloats;
64
65 return rowLen;
66 }
67
68 cl_ulong VISIBILITY_HIDDEN
matrBlockSize(SubproblemDim * dim,MatrixRole mrole,DataType dtype,clblasSide side)69 matrBlockSize(
70 SubproblemDim *dim,
71 MatrixRole mrole,
72 DataType dtype,
73 clblasSide side)
74 {
75 size_t height, pitch;
76
77 pitch = matrBlockPitch(dim, mrole, dtype, side);
78 height = matrBlockHeight(dim, mrole, side);
79
80 return (cl_ulong)height * pitch;
81 }
82
83 size_t VISIBILITY_HIDDEN
matrBlockHeight(SubproblemDim * dim,MatrixRole mrole,clblasSide side)84 matrBlockHeight(
85 SubproblemDim *dim,
86 MatrixRole mrole,
87 clblasSide side)
88 {
89 size_t ret = 0;
90
91 switch (mrole) {
92 case MATRIX_A:
93 ret = dim->y;
94 break;
95 case MATRIX_B:
96 ret = dim->x;
97 break;
98 case MATRIX_C:
99 ret = (side == clblasLeft) ? dim->y : dim->x;
100 break;
101 default:
102 break;
103 }
104
105 return ret;
106 }
107
108 void VISIBILITY_HIDDEN
kargsToProbDims(SubproblemDim * probDim,BlasFunctionID funcID,const CLBlasKargs * kargs,bool offset)109 kargsToProbDims(
110 SubproblemDim *probDim,
111 BlasFunctionID funcID,
112 const CLBlasKargs *kargs,
113 bool offset)
114 {
115
116 if (funcID == CLBLAS_SYMV) {
117 if (offset) {
118 probDim->y = kargs->offsetN;
119 probDim->x = 0;
120 probDim->bwidth = 0;
121 }
122 else {
123 probDim->y = kargs->N;
124 probDim->x = kargs->N;
125 probDim->bwidth = kargs->K;
126 }
127 }
128 else {
129 if (offset) {
130 probDim->y = kargs->offsetM;
131 probDim->x = kargs->offsetN;
132 }
133 else {
134 probDim->y = kargs->M;
135 probDim->x = kargs->N;
136 }
137
138 if (isRightSide(funcID, kargs->side)) {
139 swapDimXY(probDim);
140 }
141 if (funcID == CLBLAS_GEMV) {
142 if (kargs->transA != clblasNoTrans) {
143 swapDimXY(probDim);
144 }
145 probDim->bwidth = (offset) ? 0 : probDim->x;
146 }
147 else {
148 probDim->bwidth = (offset) ? 0 : kargs->K;
149 }
150 }
151 }
152
153 void VISIBILITY_HIDDEN
probDimsToKargs(CLBlasKargs * kargs,BlasFunctionID funcID,SubproblemDim * probDim,bool offset)154 probDimsToKargs(
155 CLBlasKargs *kargs,
156 BlasFunctionID funcID,
157 SubproblemDim *probDim,
158 bool offset)
159 {
160 size_t *m, *n;
161 SubproblemDim tmpDim;
162
163 if (offset) {
164 m = &kargs->offsetM;
165 n = &kargs->offsetN;
166 }
167 else {
168 m = &kargs->M;
169 n = &kargs->N;
170 kargs->K = probDim->bwidth;
171 }
172
173 tmpDim = *probDim;
174
175 if (isRightSide(funcID, kargs->side)) {
176 swapDimXY(&tmpDim);
177 }
178 if (funcID == CLBLAS_GEMV) {
179 if (kargs->transA != clblasNoTrans) {
180 swapDimXY(&tmpDim);
181 }
182 }
183 *m = tmpDim.y;
184 *n = tmpDim.x;
185 }
186
187