func check_level3_func(ind *linalg.IndexOpts, fn funcNum, A, B, C matrix.Matrix, pars *linalg.Parameters) (err error) { // defaults for these arows := ind.LDa brows := ind.LDb crows := ind.LDc switch fn { case fgemm: if ind.M < 0 { if pars.TransA == linalg.PNoTrans { ind.M = A.Rows() } else { ind.M = A.Cols() } } if ind.N < 0 { if pars.TransB == linalg.PNoTrans { ind.N = B.Cols() } else { ind.N = B.Rows() } } if ind.M == 0 || ind.N == 0 { return nil } if ind.K < 0 { if pars.TransA == linalg.PNoTrans { ind.K = A.Cols() } else { ind.K = A.Rows() } if pars.TransB == linalg.PNoTrans && ind.K != B.Rows() || pars.TransB != linalg.PNoTrans && ind.K != B.Cols() { return onError("dimensions of A and B do not match") } } if ind.OffsetA < 0 { return onError("offsetA illegal, <0") } if ind.LDa == 0 { ind.LDa = max(1, A.LeadingIndex()) arows = max(1, A.Rows()) } if ind.K > 0 { if (pars.TransA == linalg.PNoTrans && ind.LDa < max(1, ind.M)) || (pars.TransA != linalg.PNoTrans && ind.LDa < max(1, ind.K)) { return onError("inconsistent ldA") } sizeA := A.NumElements() if (pars.TransA == linalg.PNoTrans && sizeA < ind.OffsetA+(ind.K-1)*arows+ind.M) || (pars.TransA != linalg.PNoTrans && sizeA < ind.OffsetA+(ind.M-1)*arows+ind.K) { return onError("sizeA") } } // B matrix if ind.OffsetB < 0 { return onError("offsetB illegal, <0") } if ind.LDb == 0 { ind.LDb = max(1, B.LeadingIndex()) brows = max(1, B.Rows()) } if ind.K > 0 { if (pars.TransB == linalg.PNoTrans && ind.LDb < max(1, ind.K)) || (pars.TransB != linalg.PNoTrans && ind.LDb < max(1, ind.N)) { return onError("inconsistent ldB") } sizeB := B.NumElements() if (pars.TransB == linalg.PNoTrans && sizeB < ind.OffsetB+(ind.N-1)*brows+ind.K) || (pars.TransB != linalg.PNoTrans && sizeB < ind.OffsetB+(ind.K-1)*brows+ind.N) { return onError("sizeB") } } // C matrix if ind.OffsetC < 0 { return onError("offsetC illegal, <0") } if ind.LDc == 0 { ind.LDc = max(1, C.LeadingIndex()) crows = max(1, C.Rows()) } if ind.LDc < max(1, ind.M) { return onError("inconsistent ldC") } sizeC := C.NumElements() if sizeC < ind.OffsetC+(ind.N-1)*crows+ind.M { return onError("sizeC") } case fsymm, ftrmm, ftrsm: if ind.M < 0 { ind.M = B.Rows() if pars.Side == linalg.PLeft && (ind.M != A.Rows() || ind.M != A.Cols()) { return onError("dimensions of A and B do not match") } } if ind.N < 0 { ind.N = B.Cols() if pars.Side == linalg.PRight && (ind.N != A.Rows() || ind.N != A.Cols()) { return onError("dimensions of A and B do not match") } } if ind.M == 0 || ind.N == 0 { return } // check A if ind.OffsetB < 0 { return onError("offsetB illegal, <0") } if ind.LDa == 0 { ind.LDa = max(1, A.LeadingIndex()) arows = max(1, A.Rows()) } if pars.Side == linalg.PLeft && ind.LDa < max(1, ind.M) || ind.LDa < max(1, ind.N) { return onError("ldA") } sizeA := A.NumElements() if (pars.Side == linalg.PLeft && sizeA < ind.OffsetA+(ind.M-1)*arows+ind.M) || (pars.Side == linalg.PRight && sizeA < ind.OffsetA+(ind.N-1)*arows+ind.N) { return onError("sizeA") } if B != nil { if ind.OffsetB < 0 { return onError("offsetB illegal, <0") } if ind.LDb == 0 { ind.LDb = max(1, B.LeadingIndex()) brows = max(1, B.Rows()) } if ind.LDb < max(1, ind.M) { return onError("ldB") } sizeB := B.NumElements() if sizeB < ind.OffsetB+(ind.N-1)*brows+ind.M { return onError("sizeB") } } if C != nil { if ind.OffsetC < 0 { return onError("offsetC illegal, <0") } if ind.LDc == 0 { ind.LDc = max(1, C.LeadingIndex()) crows = max(1, C.Rows()) } if ind.LDc < max(1, ind.M) { return onError("ldC") } sizeC := C.NumElements() if sizeC < ind.OffsetC+(ind.N-1)*crows+ind.M { return onError("sizeC") } } case fsyrk: if ind.N < 0 { if pars.Trans == linalg.PNoTrans { ind.N = A.Rows() } else { ind.N = A.Cols() } //ind.N = C.Rows() } if ind.K < 0 { if pars.Trans == linalg.PNoTrans { ind.K = A.Cols() } else { ind.K = A.Rows() } } if ind.N == 0 { return } if ind.LDa == 0 { ind.LDa = max(1, A.LeadingIndex()) arows = max(1, A.Rows()) } if ind.OffsetA < 0 { return onError("offsetA") } if ind.K > 0 { if (pars.Trans == linalg.PNoTrans && ind.LDa < max(1, ind.N)) || (pars.Trans != linalg.PNoTrans && ind.LDa < max(1, ind.K)) { return onError("inconsistent ldA") } sizeA := A.NumElements() if (pars.Trans == linalg.PNoTrans && sizeA < ind.OffsetA+(ind.K-1)*arows+ind.N) || (pars.TransA != linalg.PNoTrans && sizeA < ind.OffsetA+(ind.N-1)*arows+ind.K) { return onError("sizeA") } } if ind.OffsetC < 0 { return onError("offsetC illegal, <0") } if ind.LDc == 0 { ind.LDc = max(1, C.LeadingIndex()) crows = max(1, C.Rows()) } if ind.LDc < max(1, ind.N) { return onError("ldC") } sizeC := C.NumElements() if sizeC < ind.OffsetC+(ind.N-1)*crows+ind.N { return onError("sizeC") } case fsyr2k: if ind.N < 0 { if pars.Trans == linalg.PNoTrans { ind.N = A.Rows() if ind.N != B.Rows() { return onError("dimensions of A and B do not match") } } else { ind.N = A.Cols() if ind.N != B.Cols() { return onError("dimensions of A and B do not match") } } } if ind.N == 0 { return } if ind.K < 0 { if pars.Trans == linalg.PNoTrans { ind.K = A.Cols() if ind.K != B.Cols() { return onError("dimensions of A and B do not match") } } else { ind.K = A.Rows() if ind.K != B.Rows() { return onError("dimensions of A and B do not match") } } } if ind.LDa == 0 { ind.LDa = max(1, A.LeadingIndex()) arows = max(1, A.Rows()) } if ind.K > 0 { if (pars.Trans == linalg.PNoTrans && ind.LDa < max(1, ind.N)) || (pars.Trans != linalg.PNoTrans && ind.LDa < max(1, ind.K)) { return onError("inconsistent ldA") } sizeA := A.NumElements() if (pars.Trans == linalg.PNoTrans && sizeA < ind.OffsetA+(ind.K-1)*arows+ind.N) || (pars.TransA != linalg.PNoTrans && sizeA < ind.OffsetA+(ind.N-1)*arows+ind.K) { return onError("sizeA") } } if ind.OffsetB < 0 { return onError("offsetB illegal, <0") } if ind.LDb == 0 { ind.LDb = max(1, B.LeadingIndex()) brows = max(1, B.Rows()) } if ind.K > 0 { if (pars.Trans == linalg.PNoTrans && ind.LDb < max(1, ind.N)) || (pars.Trans != linalg.PNoTrans && ind.LDb < max(1, ind.K)) { return onError("ldB") } sizeB := B.NumElements() if (pars.Trans == linalg.PNoTrans && sizeB < ind.OffsetB+(ind.K-1)*brows+ind.N) || (pars.Trans != linalg.PNoTrans && sizeB < ind.OffsetB+(ind.N-1)*brows+ind.K) { return onError("sizeB") } } if ind.OffsetC < 0 { return onError("offsetC illegal, <0") } if ind.LDc == 0 { ind.LDc = max(1, C.LeadingIndex()) crows = max(1, C.Rows()) } if ind.LDc < max(1, ind.N) { return onError("ldC") } sizeC := C.NumElements() if sizeC < ind.OffsetC+(ind.N-1)*crows+ind.N { return onError("sizeC") } } err = nil return }