template<class T, paradigm P, const bool& b> inline T Matrix<T,P,b>::dotc (const Matrix<T,P>& M) const { return DOTC (*this, M); }
CAMLprim value LFUN(gemm_trace_stub)( value vTRANSA, value vTRANSB, value vN, value vK, value vAR, value vAC, value vA, value vBR, value vBC, value vB) { CAMLparam2(vA, vB); integer GET_INT(N), GET_INT(K); char GET_INT(TRANSA), GET_INT(TRANSB); MAT_PARAMS(A); MAT_PARAMS(B); unsigned long iter_incr_A, iter_incr_B; integer dot_incr_A, dot_incr_B; NUMBER res = NUMBER_ZERO; NUMBER *last_A; caml_enter_blocking_section(); /* Allow other threads */ if (TRANSA == 'N') { if (TRANSB == 'N') { if (N < K) { iter_incr_A = 1; dot_incr_A = rows_A; iter_incr_B = rows_B; dot_incr_B = 1; } else { NUMBER *tmp_A_data = A_data; integer tmp_N = N; A_data = B_data; B_data = tmp_A_data; N = K; K = tmp_N; iter_incr_A = 1; dot_incr_A = rows_B; iter_incr_B = rows_A; dot_incr_B = 1; } } else { if (N == rows_A && N == rows_B) { integer NK = N * K; res = #ifdef LACAML_COMPLEX (TRANSB == 'C') ? DOTC(&NK, B_data, &integer_one, A_data, &integer_one) : #endif DOTU(&NK, B_data, &integer_one, A_data, &integer_one); goto end; } else { integer tmp_N = N; NUMBER *tmp_A_data = A_data; A_data = B_data; B_data = tmp_A_data; N = K; K = tmp_N; iter_incr_A = rows_B; dot_incr_A = 1; iter_incr_B = rows_A; dot_incr_B = 1; } } } else { if (TRANSB == 'N') { if (K == rows_A && K == rows_B) { integer NK = N * K; res = #ifdef LACAML_COMPLEX (TRANSA == 'C') ? DOTC(&NK, A_data, &integer_one, B_data, &integer_one) : #endif DOTU(&NK, A_data, &integer_one, B_data, &integer_one); goto end; } else { iter_incr_A = rows_A; dot_incr_A = 1; iter_incr_B = rows_B; dot_incr_B = 1; } } else { if (N < K) { NUMBER *tmp_A_data = A_data; integer tmp_N = N; A_data = B_data; B_data = tmp_A_data; N = K; K = tmp_N; iter_incr_A = rows_B; dot_incr_A = 1; iter_incr_B = 1; dot_incr_B = rows_A; } else { iter_incr_A = rows_A; dot_incr_A = 1; iter_incr_B = 1; dot_incr_B = rows_B; } } } last_A = A_data + N * iter_incr_A; #ifndef LACAML_COMPLEX /* Real number */ COMMON_GEMM_TRACE_LOOP #else /* Complex number */ if (TRANSA == 'C') if (TRANSB == 'C') while (A_data != last_A) { NUMBER cd = DOTU(&K, A_data, &dot_incr_A, B_data, &dot_incr_B); NUMBER d = COMLEX_CONJ(cd); res = ADD_NUMBER(res, d); GEMM_TRACE_INCR; } else while (A_data != last_A) { NUMBER d = DOTC(&K, A_data, &dot_incr_A, B_data, &dot_incr_B); res = ADD_NUMBER(res, d); GEMM_TRACE_INCR; } else if (TRANSB == 'C') while (A_data != last_A) { NUMBER d = DOTC(&K, B_data, &dot_incr_B, A_data, &dot_incr_A); res = ADD_NUMBER(res, d); GEMM_TRACE_INCR; } else COMMON_GEMM_TRACE_LOOP #endif end: caml_leave_blocking_section(); /* Disallow other threads */ CAMLreturn(COPY_NUMBER(res)); }