| 199 | } |
| 200 | |
| 201 | clblasStatus SGEMM_mod1024( |
| 202 | clblasTranspose transA, |
| 203 | clblasTranspose transB, |
| 204 | cl_uint M, cl_uint N, cl_uint K, |
| 205 | float alpha, |
| 206 | cl_mem A, cl_uint offA, cl_uint lda, |
| 207 | cl_mem B, cl_uint offB, cl_uint ldb, |
| 208 | float beta, |
| 209 | cl_mem C, cl_uint offC, cl_uint ldc, |
| 210 | cl_uint numCommandQueues, |
| 211 | cl_command_queue *commandQueues, |
| 212 | cl_uint numEventsInWaitList, |
| 213 | const cl_event *eventWaitList, |
| 214 | cl_event *events, |
| 215 | bool &specialCaseHandled) |
| 216 | { |
| 217 | const char *tileKernelSource = NULL; |
| 218 | cl_kernel *tileClKernel = NULL; |
| 219 | size_t tileKernelBinarySize = 0; |
| 220 | cl_int err; |
| 221 | |
| 222 | |
| 223 | const unsigned char *tileKernelBinary = NULL; |
| 224 | |
| 225 | clblasStatus status; |
| 226 | |
| 227 | |
| 228 | //split the kernel calls to handle sgemm NT perf drop at big multiples of 1024 |
| 229 | if ((lda % 1024 == 0) && (ldb % 1024 == 0) && (K > lda / 4)) |
| 230 | { |
| 231 | if ((lda == ldb) && (lda >= 4096) && (lda <= 8192)) // between 4096 and 8192 for now |
| 232 | { |
| 233 | if (lda != 6144)// 6144 is handled by 96 x 96 kernel |
| 234 | { |
| 235 | // we are going to call 16 GEMMs with M=M/2, N=N/2, K=K/4 |
| 236 | // each GEMM requires M%128 == 0, N%128 == 0, K%16 == 0 |
| 237 | if (M % 256 == 0 && N % 256 == 0 && K % 64 == 0) |
| 238 | { |
| 239 | if (!((transA == clblasNoTrans) && (transB == clblasTrans))) |
| 240 | return clblasNotImplemented; |
| 241 | |
| 242 | specialCaseHandled = true; |
| 243 | unsigned int M_split_factor; |
| 244 | unsigned int N_split_factor; |
| 245 | unsigned int K_split_factor; |
| 246 | |
| 247 | if (lda < 7168) |
| 248 | { |
| 249 | M_split_factor = 1; |
| 250 | N_split_factor = 1; |
| 251 | K_split_factor = 1; |
| 252 | } |
| 253 | else |
| 254 | { |
| 255 | //7168, 8192 |
| 256 | M_split_factor = 2; |
| 257 | N_split_factor = 2; |
| 258 | K_split_factor = 4; |
no test coverage detected