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