149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang/*
249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang * Copyright (C) 2015 The Android Open Source Project
349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang *
449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang * Licensed under the Apache License, Version 2.0 (the "License");
549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang * you may not use this file except in compliance with the License.
649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang * You may obtain a copy of the License at
749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang *
849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang *      http://www.apache.org/licenses/LICENSE-2.0
949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang *
1049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang * Unless required by applicable law or agreed to in writing, software
1149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang * distributed under the License is distributed on an "AS IS" BASIS,
1249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang * See the License for the specific language governing permissions and
1449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang * limitations under the License.
1549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang */
1649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
1749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
1849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang#include "RenderScript.h"
1949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang#include "rsCppInternal.h"
2049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
2193ddf62ab18ed17d96189a602a8cbde83712a3e9Miao Wang#define NELEM(m) (sizeof(m) / sizeof((m)[0]))
2293ddf62ab18ed17d96189a602a8cbde83712a3e9Miao Wang
23dfcfabfccad8a8f2f42f83081638c7e5c9bfb4b9Chih-Hung Hsiehusing android::RSC::Allocation;
24dfcfabfccad8a8f2f42f83081638c7e5c9bfb4b9Chih-Hung Hsiehusing android::RSC::Element;
25dfcfabfccad8a8f2f42f83081638c7e5c9bfb4b9Chih-Hung Hsiehusing android::RSC::RS;
26dfcfabfccad8a8f2f42f83081638c7e5c9bfb4b9Chih-Hung Hsiehusing android::RSC::RS_ERROR_INVALID_ELEMENT;
27dfcfabfccad8a8f2f42f83081638c7e5c9bfb4b9Chih-Hung Hsiehusing android::RSC::RS_ERROR_INVALID_PARAMETER;
28dfcfabfccad8a8f2f42f83081638c7e5c9bfb4b9Chih-Hung Hsiehusing android::RSC::RS_SUCCESS;
29dfcfabfccad8a8f2f42f83081638c7e5c9bfb4b9Chih-Hung Hsiehusing android::RSC::ScriptIntrinsicBLAS;
30dfcfabfccad8a8f2f42f83081638c7e5c9bfb4b9Chih-Hung Hsiehusing android::RSC::sp;
3149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
3249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang// ScriptIntrinsicBLAS APIS
3349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao WangScriptIntrinsicBLAS::ScriptIntrinsicBLAS(sp<RS> rs, sp<const Element> e)
3449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    : ScriptIntrinsic(rs, RS_SCRIPT_INTRINSIC_ID_BLAS, e) {
3549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
3649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
3749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
3845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehsp<ScriptIntrinsicBLAS> ScriptIntrinsicBLAS::create(const sp<RS>& rs) {
3949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    return new ScriptIntrinsicBLAS(rs, Element::U32(rs));
4049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
4149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
4249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangenum RsBlasDataType {
4349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    SINGLE,
4449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    DOUBLE,
4549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    SINGLE_COMPLEX,
4649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    DOUBLE_COMPLEX
4749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang};
4849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
4949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangstatic RsBlasCall
5049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao WangsetUpBLASCall(RsBlasDataType dataType, RsBlasFunction func,
5149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang              int TransA, int TransB, int Side, int Uplo, int Diag,
5249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang              int M, int N, int K, int incX, int incY, int KL, int KU,
5349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang              float alphaF, float betaF, double alphaD, double betaD,
5449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang              float alphaCX, float alphaCY, float betaCX, float betaCY,
5549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang              double alphaZX, double alphaZY, double betaZX, double betaZY
5649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang              ) {
5749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    RsBlasCall call;
5849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    memset(&call, 0, sizeof(call));
5949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.func = func;
6049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.transA = (RsBlasTranspose)TransA;
6149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.transB = (RsBlasTranspose)TransB;
6249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.side = (RsBlasSide)Side;
6349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.uplo = (RsBlasUplo)Uplo;
6449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.diag = (RsBlasDiag)Diag;
6549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.M = M;
6649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.N = N;
6749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.K = K;
6849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
6949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    switch (dataType) {
7049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        case SINGLE:
7149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            // For Single-precision BLAS.
7249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            call.alpha.f = alphaF;
7349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            call.beta.f = betaF;
7449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            break;
7549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        case DOUBLE:
7649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            // For Double-precision BLAS.
7749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            call.alpha.d = alphaD;
7849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            call.beta.d = betaD;
7949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            break;
8049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        case SINGLE_COMPLEX:
8149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            // For Single-precision complex BLAS.
8249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            call.alpha.c.r = alphaCX;
8349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            call.alpha.c.i = alphaCY;
8449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            call.beta.c.r = betaCX;
8549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            call.beta.c.i = betaCY;
8649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            break;
8749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        case DOUBLE_COMPLEX:
8849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            // For Double-precision complex BLAS.
8949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            call.alpha.z.r = alphaZX;
9049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            call.alpha.z.i = alphaZY;
9149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            call.beta.z.r = betaZX;
9249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            call.beta.z.i = betaZY;
9349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            break;
9449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        default:
9549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            break;
9649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
9749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
9849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.incX = incX;
9949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.incY = incY;
10049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.KL = KL;
10149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.KU = KU;
10249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
10349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    return call;
10449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
10549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
10649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangstatic void
10749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao WangnScriptIntrinsicBLAS_Single(RS* mRS, RsContext con, RsScript id, RsBlasFunction func, int TransA,
10849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                            int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
10949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                            float alpha, RsAllocation A, RsAllocation B,
11049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                            float beta, RsAllocation C, int incX, int incY, int KL, int KU) {
11149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    RsBlasCall call = setUpBLASCall(SINGLE, func, TransA, TransB, Side, Uplo, Diag,
11249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                    M, N, K, incX, incY, KL, KU, alpha, beta, 0.0, 0.0,
11349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                    0.0f, 0.0f, 0.0f, 0.0f, 0.0, 0.0, 0.0, 0.0);
11449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    RsAllocation in_allocs[3] = {A, B, C};
11593ddf62ab18ed17d96189a602a8cbde83712a3e9Miao Wang    tryDispatch(mRS, RS::dispatch->ScriptForEachMulti(con, id, 0, in_allocs, NELEM(in_allocs), nullptr,
11649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                                      &call, sizeof(call), nullptr, 0));
11749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
11849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
11949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
12049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangstatic void
12149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao WangnScriptIntrinsicBLAS_Double(RS* mRS, RsContext con, RsScript id, RsBlasFunction func, int TransA,
12249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                            int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
12349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                            double alpha, RsAllocation A, RsAllocation B,
12449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                            double beta, RsAllocation C, int incX, int incY, int KL, int KU) {
12549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    RsBlasCall call = setUpBLASCall(DOUBLE, func, TransA, TransB, Side, Uplo, Diag,
12649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                    M, N, K, incX, incY, KL, KU, 0.0f, 0.0f, alpha, beta,
12749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                    0.0f, 0.0f, 0.0f, 0.0f, 0.0, 0.0, 0.0, 0.0);
12849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    RsAllocation in_allocs[3] = {A, B, C};
12993ddf62ab18ed17d96189a602a8cbde83712a3e9Miao Wang    tryDispatch(mRS, RS::dispatch->ScriptForEachMulti(con, id, 0, in_allocs, NELEM(in_allocs), nullptr,
13049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                                      &call, sizeof(call), nullptr, 0));
13149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
13249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
13349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangstatic void
13449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao WangnScriptIntrinsicBLAS_Complex(RS* mRS, RsContext con, RsScript id, RsBlasFunction func, int TransA,
13549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                             int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
13649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                             float alphaX, float alphaY, RsAllocation A, RsAllocation B,
13749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                             float betaX, float betaY, RsAllocation C, int incX, int incY, int KL, int KU) {
13849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    RsBlasCall call = setUpBLASCall(SINGLE_COMPLEX, func, TransA, TransB, Side, Uplo, Diag,
13949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                    M, N, K, incX, incY, KL, KU, 0.0f, 0.0f, 0.0, 0.0,
14049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                    alphaX, alphaY, betaX, betaY, 0.0, 0.0, 0.0, 0.0);
14149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    RsAllocation in_allocs[3] = {A, B, C};
14293ddf62ab18ed17d96189a602a8cbde83712a3e9Miao Wang    tryDispatch(mRS, RS::dispatch->ScriptForEachMulti(con, id, 0, in_allocs, NELEM(in_allocs), nullptr,
14349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                                      &call, sizeof(call), nullptr, 0));
14449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
14549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
14649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangstatic void
14749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao WangnScriptIntrinsicBLAS_Z(RS* mRS, RsContext con, RsScript id, RsBlasFunction func, int TransA,
14849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                       int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
14949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                       double alphaX, double alphaY, RsAllocation A, RsAllocation B,
15049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                       double betaX, double betaY, RsAllocation C, int incX, int incY, int KL, int KU) {
15149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    RsBlasCall call = setUpBLASCall(DOUBLE_COMPLEX, func, TransA, TransB, Side, Uplo, Diag,
15249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                    M, N, K, incX, incY, KL, KU, 0.0f, 0.0f, 0.0, 0.0,
15349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                    0.0f, 0.0f, 0.0f, 0.0f, alphaX, alphaY, betaX, betaY);
15449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    RsAllocation in_allocs[3] = {A, B, C};
15593ddf62ab18ed17d96189a602a8cbde83712a3e9Miao Wang    tryDispatch(mRS, RS::dispatch->ScriptForEachMulti(con, id, 0, in_allocs, NELEM(in_allocs), nullptr,
15649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                                      &call, sizeof(call), nullptr, 0));
15749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
15849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
15949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
16049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangstatic void
16149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao WangnScriptIntrinsicBLAS_BNNM(RS* mRS, RsContext con, RsScript id, int M, int N, int K,
16249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                          RsAllocation A, int a_offset, RsAllocation B, int b_offset,
16349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                          RsAllocation C, int c_offset, int c_mult_int) {
16449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    RsBlasCall call;
16549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    memset(&call, 0, sizeof(call));
16649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.func = RsBlas_bnnm;
16749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.M = M;
16849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.N = N;
16949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.K = K;
17049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.a_offset = a_offset & 0xFF;
17149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.b_offset = b_offset & 0xFF;
17249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.c_offset = c_offset;
17349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    call.c_mult_int = c_mult_int;
17449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
17549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    RsAllocation in_allocs[3] = {A, B, C};
17693ddf62ab18ed17d96189a602a8cbde83712a3e9Miao Wang    tryDispatch(mRS, RS::dispatch->ScriptForEachMulti(con, id, 0, in_allocs, NELEM(in_allocs), nullptr,
17749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                                      &call, sizeof(call), nullptr, 0));
17849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
17949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
18049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang/**
18149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang * Level 2 BLAS
18249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang */
18345768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic void validateGEMV(RS* mRS, const sp<const Element>& e, RsBlasTranspose TransA, const sp<Allocation>& A,
18445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                         const sp<Allocation>& X, int incX, const sp<Allocation>& Y, int incY) {
18549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = A->getType()->getY();
18649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
18749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (!A->getType()->getElement()->isCompatible(e) ||
18849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !X->getType()->getElement()->isCompatible(e) ||
18949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !Y->getType()->getElement()->isCompatible(e)) {
19049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
19149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
19249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (X->getType()->getY() > 1 || Y->getType()->getY() > 1) {
19349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "BLAS vectors must have Y dimension of 0 or 1");
19449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
19549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
19649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (incX <= 0 || incY <= 0) {
19749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Vector increments must be greater than 0");
19849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
19949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int expectedXDim = -1, expectedYDim = -1;
20049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (TransA == RsBlasNoTrans) {
20149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        expectedXDim = 1 + (N - 1) * incX;
20249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        expectedYDim = 1 + (M - 1) * incY;
20349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
20449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        expectedXDim = 1 + (M - 1) * incX;
20549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        expectedYDim = 1 + (N - 1) * incY;
20649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
20749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)X->getType()->getX() != expectedXDim ||
20849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        (int)Y->getType()->getX() != expectedYDim) {
20949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Incorrect vector dimensions for GEMV");
21049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
21149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
21249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
21345768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::SGEMV(RsBlasTranspose TransA, float alpha, const sp<Allocation>& A, const sp<Allocation>& X,
21445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int incX, float beta, const sp<Allocation>& Y, int incY) {
21549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateGEMV(mRS, Element::F32(mRS), TransA, A, X, incX, Y, incY);
21649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = A->getType()->getY();
21749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
21849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_sgemv,
21949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, 0, 0, 0, M, N, 0,
22049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                alpha, A->getID(), X->getID(),
22149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                beta, Y->getID(), incX, incY, 0, 0);
22249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
22349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
22445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::DGEMV(RsBlasTranspose TransA, double alpha, const sp<Allocation>& A, const sp<Allocation>& X,
22545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int incX, double beta, const sp<Allocation>& Y, int incY) {
22649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateGEMV(mRS, Element::F64(mRS), TransA, A, X, incX, Y, incY);
22749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = A->getType()->getY();
22849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
22949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dgemv,
23049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, 0, 0, 0, M, N, 0,
23149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                alpha, A->getID(), X->getID(),
23249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                beta, Y->getID(), incX, incY, 0, 0);
23349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
23449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
23545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::CGEMV(RsBlasTranspose TransA, Float2 alpha, const sp<Allocation>& A, const sp<Allocation>& X,
23645768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int incX, Float2 beta, const sp<Allocation>& Y, int incY) {
23749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateGEMV(mRS, Element::F32_2(mRS), TransA, A, X, incX, Y, incY);
23849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = A->getType()->getY();
23949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
24049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_cgemv,
24149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 TransA, 0, 0, 0, 0, M, N, 0,
24249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha.x, alpha.y, A->getID(), X->getID(),
24349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 beta.x, beta.y, Y->getID(), incX, incY, 0, 0);
24449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
24549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
24645768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::ZGEMV(RsBlasTranspose TransA, Double2 alpha, const sp<Allocation>& A, const sp<Allocation>& X,
24745768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int incX, Double2 beta, const sp<Allocation>& Y, int incY) {
24849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateGEMV(mRS, Element::F64_2(mRS), TransA, A, X, incX, Y, incY);
24949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = A->getType()->getY();
25049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
25149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zgemv,
25249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           TransA, 0, 0, 0, 0, M, N, 0,
25349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha.x, alpha.y, A->getID(), X->getID(),
25449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           beta.x, beta.y, Y->getID(), incX, incY, 0, 0);
25549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
25649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
25745768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::SGBMV(RsBlasTranspose TransA, int KL, int KU, float alpha, const sp<Allocation>& A,
25845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& X, int incX, float beta, const sp<Allocation>& Y, int incY) {
25949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // GBMV has the same validation requirements as GEMV + KL and KU >= 0
26049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateGEMV(mRS, Element::F32(mRS), TransA, A, X, incX, Y, incY);
26149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (KL < 0 || KU < 0) {
26249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "KL and KU must be greater than or equal to 0");
26349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
26449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = A->getType()->getY();
26549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
26649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
26749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_sgbmv,
26849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, 0, 0, 0, M, N, 0,
26949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                alpha, A->getID(), X->getID(),
27049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                beta, Y->getID(), incX, incY, KL, KU);
27149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
27249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
27345768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::DGBMV(RsBlasTranspose TransA, int KL, int KU, double alpha, const sp<Allocation>& A,
27445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& X, int incX, double beta, const sp<Allocation>& Y, int incY) {
27549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // GBMV has the same validation requirements as GEMV + KL and KU >= 0
27649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateGEMV(mRS, Element::F64(mRS), TransA, A, X, incX, Y, incY);
27749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (KL < 0 || KU < 0) {
27849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "KL and KU must be greater than or equal to 0");
27949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
28049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = A->getType()->getY();
28149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
28249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
28349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dgbmv,
28449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, 0, 0, 0, M, N, 0,
28549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                alpha, A->getID(), X->getID(),
28649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                beta, Y->getID(), incX, incY, KL, KU);
28749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
28849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
28945768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::CGBMV(RsBlasTranspose TransA, int KL, int KU, Float2 alpha, const sp<Allocation>& A,
29045768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& X, int incX, Float2 beta, const sp<Allocation>& Y, int incY) {
29149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // GBMV has the same validation requirements as GEMV + KL and KU >= 0
29249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateGEMV(mRS, Element::F32_2(mRS), TransA, A, X, incX, Y, incY);
29349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (KL < 0 || KU < 0) {
29449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "KL and KU must be greater than or equal to 0");
29549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
29649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = A->getType()->getY();
29749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
29849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
29949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_cgbmv,
30049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 TransA, 0, 0, 0, 0, M, N, 0,
30149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha.x, alpha.y, A->getID(), X->getID(),
30249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 beta.x, beta.y, Y->getID(), incX, incY, KL, KU);
30349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
30449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
30545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::ZGBMV(RsBlasTranspose TransA, int KL, int KU, Double2 alpha, const sp<Allocation>& A,
30645768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& X, int incX, Double2 beta, const sp<Allocation>& Y, int incY) {
30749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // GBMV has the same validation requirements as GEMV + KL and KU >= 0
30849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateGEMV(mRS, Element::F64_2(mRS), TransA, A, X, incX, Y, incY);
30949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (KL < 0 || KU < 0) {
31049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "KL and KU must be greater than or equal to 0");
31149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
31249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = A->getType()->getY();
31349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
31449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
31549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zgbmv,
31649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           TransA, 0, 0, 0, 0, M, N, 0,
31749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha.x, alpha.y, A->getID(), X->getID(),
31849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           beta.x, beta.y, Y->getID(), incX, incY, KL, KU);
31949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
32049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
32145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic void validateTRMV(RS* mRS, const sp<const Element>& e, RsBlasUplo Uplo, RsBlasTranspose TransA,
32245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                         RsBlasDiag Diag, const sp<Allocation>& A, const sp<Allocation>& X, int incX) {
32349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
32449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)A->getType()->getX() != N) {
32549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "A must be a square matrix for TRMV");
32649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
32749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (!A->getType()->getElement()->isCompatible(e) ||
32849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !X->getType()->getElement()->isCompatible(e)) {
32949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
33049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
33149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (X->getType()->getY() > 1) {
33249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "BLAS vectors must have Y dimension of 0 or 1");
33349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
33449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
33549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (incX <= 0) {
33649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Vector increments must be greater than 0");
33749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
33849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int expectedXDim = 1 + (N - 1) * incX;
33949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)X->getType()->getX() != expectedXDim) {
34049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Incorrect vector dimensions for TRMV");
34149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
34249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
34349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
34445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic int validateTPMV(RS* mRS, const sp<const Element>& e,  RsBlasUplo Uplo, RsBlasTranspose TransA,
34545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                        RsBlasDiag Diag, const sp<Allocation>& Ap, const sp<Allocation>& X, int incX) {
34649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (!Ap->getType()->getElement()->isCompatible(e) ||
34749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !X->getType()->getElement()->isCompatible(e)) {
34849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
34949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
35049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (X->getType()->getY() > 1) {
35149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "BLAS vectors must have Y dimension of 0 or 1");
35249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
35349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
35449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Ap->getType()->getY() > 1) {
35549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Ap must have a Y dimension of 0 or 1");
35649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
35749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
35849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = sqrt((double)Ap->getType()->getX() * 2);
35949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)Ap->getType()->getX() != ((N * (N+1)) / 2)) {
36049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid dimension for Ap");
36149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
36249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (incX <= 0) {
36349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Vector increments must be greater than 0");
36449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
36549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int expectedXDim = 1 + (N - 1) * incX;
36649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)X->getType()->getX() != expectedXDim) {
36749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Incorrect vector dimensions for TPMV");
36849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
36949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
37049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    return N;
37149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
37249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
37349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
37449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::STRMV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
37545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, const sp<Allocation>& X, int incX) {
37649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMV(mRS, Element::F32(mRS), Uplo, TransA, Diag, A, X, incX);
37749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
37849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_strmv,
37949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, 0, Uplo, Diag, 0, N, 0, 0,
38049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                A->getID(), X->getID(), 0, 0, incX, 0, 0, 0);
38149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
38249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
38349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::DTRMV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
38445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, const sp<Allocation>& X, int incX) {
38549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMV(mRS, Element::F64(mRS), Uplo, TransA, Diag, A, X, incX);
38649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
38749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dtrmv,
38849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, 0, Uplo, Diag, 0, N, 0, 0,
38949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                A->getID(), X->getID(), 0, 0, incX, 0, 0, 0);
39049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
39149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
39249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::CTRMV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
39345768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, const sp<Allocation>& X, int incX) {
39449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMV(mRS, Element::F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
39549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
39649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_ctrmv,
39749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0,
39849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 A->getID(), X->getID(), 0, 0, 0, incX, 0, 0, 0);
39949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
40049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
40149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::ZTRMV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
40245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, const sp<Allocation>& X, int incX) {
40349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMV(mRS, Element::F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
40449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
40549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_ztrmv,
40649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0,
40749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           A->getID(), X->getID(), 0, 0, 0, incX, 0, 0, 0);
40849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
40949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
41049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::STBMV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
41145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int K, const sp<Allocation>& A, const sp<Allocation>& X, int incX) {
41249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // TBMV has the same requirements as TRMV + K >= 0
41349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (K < 0) {
41449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "K must be greater than or equal to 0");
41549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
41649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMV(mRS, Element::F32(mRS), Uplo, TransA, Diag, A, X, incX);
41749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
41849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_stbmv,
41949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, 0, Uplo, Diag, 0, N, K, 0,
42049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                A->getID(), X->getID(), 0, 0, incX, 0, 0, 0);
42149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
42249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
42349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::DTBMV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
42445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int K, const sp<Allocation>& A, const sp<Allocation>& X, int incX) {
42549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // TBMV has the same requirements as TRMV + K >= 0
42649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (K < 0) {
42749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "K must be greater than or equal to 0");
42849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
42949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMV(mRS, Element::F64(mRS), Uplo, TransA, Diag, A, X, incX);
43049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
43149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dtbmv,
43249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, 0, Uplo, Diag, 0, N, K, 0,
43349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                A->getID(), X->getID(), 0, 0, incX, 0, 0, 0);
43449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
43549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
43649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::CTBMV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
43745768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int K, const sp<Allocation>& A, const sp<Allocation>& X, int incX) {
43849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // TBMV has the same requirements as TRMV + K >= 0
43949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (K < 0) {
44049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "K must be greater than or equal to 0");
44149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
44249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMV(mRS, Element::F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
44349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
44449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_ctbmv,
44549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0,
44649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 A->getID(), X->getID(), 0, 0, 0, incX, 0, 0, 0);
44749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
44849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
44949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::ZTBMV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
45045768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int K, const sp<Allocation>& A, const sp<Allocation>& X, int incX) {
45149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // TBMV has the same requirements as TRMV + K >= 0
45249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (K < 0) {
45349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "K must be greater than or equal to 0");
45449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
45549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMV(mRS, Element::F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
45649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
45749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_ztbmv,
45849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0,
45949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           A->getID(), X->getID(), 0, 0, 0, incX, 0, 0, 0);
46049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
46149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
46249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::STPMV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
46345768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Ap, const sp<Allocation>& X, int incX) {
46449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateTPMV(mRS, Element::F32(mRS), Uplo, TransA, Diag, Ap, X, incX);
46549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_stpmv,
46649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, 0, Uplo, Diag, 0, N, 0, 0,
46749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                Ap->getID(), X->getID(), 0, 0, incX, 0, 0, 0);
46849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
46949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
47049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::DTPMV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
47145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Ap, const sp<Allocation>& X, int incX) {
47249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateTPMV(mRS, Element::F64(mRS), Uplo, TransA, Diag, Ap, X, incX);
47349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dtpmv,
47449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, 0, Uplo, Diag, 0, N, 0, 0,
47549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                Ap->getID(), X->getID(), 0, 0, incX, 0, 0, 0);
47649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
47749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
47849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::CTPMV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
47945768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Ap,  const sp<Allocation>& X,  int incX) {
48049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateTPMV(mRS, Element::F32_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
48149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_ctpmv,
48249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0,
48349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 Ap->getID(), X->getID(), 0, 0, 0, incX, 0, 0, 0);
48449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
48549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
48649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::ZTPMV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
48745768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Ap, const sp<Allocation>& X, int incX) {
48849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateTPMV(mRS, Element::F64_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
48949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_ztpmv,
49049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0,
49149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           Ap->getID(), X->getID(), 0, 0, 0, incX, 0, 0, 0);
49249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
49349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
49449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::STRSV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
49545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, const sp<Allocation>& X, int incX) {
49649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // TRSV is the same as TRMV
49749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMV(mRS, Element::F32(mRS), Uplo, TransA, Diag, A, X, incX);
49849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
49949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_strsv,
50049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, 0, Uplo, Diag, 0, N, 0, 0,
50149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                A->getID(), X->getID(), 0, 0, incX, 0, 0, 0);
50249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
50349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
50449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::DTRSV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
50545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A,  const sp<Allocation>& X,  int incX) {
50649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // TRSV is the same as TRMV
50749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMV(mRS, Element::F64(mRS), Uplo, TransA, Diag, A, X, incX);
50849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
50949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dtrsv,
51049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, 0, Uplo, Diag, 0, N, 0, 0,
51149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                A->getID(), X->getID(), 0, 0, incX, 0, 0, 0);
51249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
51349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
51449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
51549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::CTRSV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
51645768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, const sp<Allocation>& X, int incX) {
51749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // TRSV is the same as TRMV
51849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMV(mRS, Element::F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
51949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
52049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_ctrsv,
52149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0,
52249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 A->getID(), X->getID(), 0, 0, 0, incX, 0, 0, 0);
52349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
52449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
52549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
52649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::ZTRSV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
52745768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, const sp<Allocation>& X, int incX) {
52849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // TRSV is the same as TRMV
52949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMV(mRS, Element::F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
53049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
53149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_ztrsv,
53249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0,
53349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           A->getID(), X->getID(), 0, 0, 0, incX, 0, 0, 0);
53449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
53549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
53649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
53749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::STBSV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
53845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int K, const sp<Allocation>& A, const sp<Allocation>& X, int incX) {
53949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // TBSV is the same as TRMV + K >= 0
54049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMV(mRS, Element::F32(mRS), Uplo, TransA, Diag, A, X, incX);
54149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
54249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (K < 0) {
54349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Number of diagonals must be positive");
54449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
54549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_stbsv,
54649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, 0, Uplo, Diag, 0, N, K, 0,
54749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                A->getID(), X->getID(), 0, 0, incX, 0, 0, 0);
54849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
54949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
55049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::DTBSV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
55145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int K, const sp<Allocation>& A, const sp<Allocation>& X, int incX) {
55249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // TBSV is the same as TRMV + K >= 0
55349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMV(mRS, Element::F64(mRS), Uplo, TransA, Diag, A, X, incX);
55449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
55549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (K < 0) {
55649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Number of diagonals must be positive");
55749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
55849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dtbsv,
55949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, 0, Uplo, Diag, 0, N, K, 0,
56049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                A->getID(), X->getID(), 0, 0, incX, 0, 0, 0);
56149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
56249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
56349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::CTBSV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
56445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int K, const sp<Allocation>& A, const sp<Allocation>& X, int incX) {
56549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // TBSV is the same as TRMV + K >= 0
56649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMV(mRS, Element::F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
56749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
56849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (K < 0) {
56949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Number of diagonals must be positive");
57049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
57149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_ctbsv,
57249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 TransA, 0, 0, Uplo, Diag, 0, N, K,
57349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, A->getID(), X->getID(), 0, 0, 0, incX, 0, 0, 0);
57449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
57549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
57649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::ZTBSV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
57745768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int K, const sp<Allocation>& A, const sp<Allocation>& X, int incX) {
57849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // TBSV is the same as TRMV + K >= 0
57949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMV(mRS, Element::F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
58049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
58149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (K < 0) {
58249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Number of diagonals must be positive");
58349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
58449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_ztbsv,
58549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0,
58649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           A->getID(), X->getID(), 0, 0, 0, incX, 0, 0, 0);
58749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
58849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
58949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::STPSV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
59045768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Ap, const sp<Allocation>& X, int incX) {
59149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // TPSV is same as TPMV
59249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateTPMV(mRS, Element::F32(mRS), Uplo, TransA, Diag, Ap, X, incX);
59349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_stpsv,
59449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, 0, Uplo, Diag, 0, N, 0, 0,
59549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                Ap->getID(), X->getID(), 0, 0, incX, 0, 0, 0);
59649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
59749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
59849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::DTPSV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
59945768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Ap, const sp<Allocation>& X, int incX) {
60049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // TPSV is same as TPMV
60149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateTPMV(mRS, Element::F64(mRS), Uplo, TransA, Diag, Ap, X, incX);
60249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dtpsv,
60349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, 0, Uplo, Diag, 0, N, 0, 0,
60449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                Ap->getID(), X->getID(), 0, 0, incX, 0, 0, 0);
60549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
60649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
60749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::CTPSV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
60845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Ap, const sp<Allocation>& X, int incX) {
60949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // TPSV is same as TPMV
61049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateTPMV(mRS, Element::F32_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
61149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_ctpsv,
61249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0,
61349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 Ap->getID(), X->getID(), 0, 0, 0, incX, 0, 0, 0);
61449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
61549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
61649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::ZTPSV(RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
61745768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Ap, const sp<Allocation>& X, int incX) {
61849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // TPSV is same as TPMV
61949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateTPMV(mRS, Element::F64_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
62049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_ztpsv,
62149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0,
62249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           Ap->getID(), X->getID(), 0, 0, 0, incX, 0, 0, 0);
62349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
62449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
62549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang/**
62649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang * Level 2, S and D only
62749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang */
62845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic int validateSYMV(RS* mRS, const sp<const Element>& e, RsBlasUplo Uplo, const sp<Allocation>& A,
62945768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                        const sp<Allocation>& X, const sp<Allocation>& Y, int incX, int incY) {
63049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getY();
63149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)A->getType()->getX() != N) {
63249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "A must be a square matrix for SYMV");
63349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
63449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (!A->getType()->getElement()->isCompatible(e) ||
63549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !X->getType()->getElement()->isCompatible(e) ||
63649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !Y->getType()->getElement()->isCompatible(e) ) {
63749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
63849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
63949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (X->getType()->getY() > 1 || Y->getType()->getY() > 1) {
64049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "BLAS vectors must have Y dimension of 0 or 1");
64149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
64249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
64349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (incX <= 0 || incY <= 0) {
64449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Vector increments must be greater than 0");
64549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
64649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int expectedXDim = 1 + (N - 1) * incX;
64749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)X->getType()->getX() != expectedXDim) {
64849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Incorrect vector dimensions for SYMV");
64949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
65049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int expectedYDim = 1 + (N - 1) * incY;
65149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)Y->getType()->getX() != expectedYDim) {
65249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Incorrect vector dimensions for SYMV");
65349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
65449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    return N;
65549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
65645768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic int validateSPMV(RS* mRS, const sp<const Element>& e, RsBlasUplo Uplo, const sp<Allocation>& Ap,
65745768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                        const sp<Allocation>& X, int incX, const sp<Allocation>& Y, int incY) {
65849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (!Ap->getType()->getElement()->isCompatible(e) ||
65949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !X->getType()->getElement()->isCompatible(e) ||
66049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !Y->getType()->getElement()->isCompatible(e)) {
66149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
66249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
66349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (X->getType()->getY() > 1 || Y->getType()->getY() > 1) {
66449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "BLAS vectors must have Y dimension of 0 or 1");
66549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
66649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
66749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Ap->getType()->getY() > 1) {
66849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Ap must have a Y dimension of 0 or 1");
66949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
67049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
67149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = sqrt((double)Ap->getType()->getX() * 2);
67249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)Ap->getType()->getX() != ((N * (N+1)) / 2)) {
67349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid dimension for Ap");
67449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
67549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (incX <= 0 || incY <= 0) {
67649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Vector increments must be greater than 0");
67749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
67849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int expectedXDim = 1 + (N - 1) * incX;
67949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)X->getType()->getX() != expectedXDim) {
68049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Incorrect vector dimensions for SPMV");
68149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
68249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int expectedYDim = 1 + (N - 1) * incY;
68349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)Y->getType()->getX() != expectedYDim) {
68449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Incorrect vector dimensions for SPMV");
68549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
68649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
68749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    return N;
68849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
68945768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic void validateGER(RS* mRS, const sp<const Element>& e, const sp<Allocation>& X, int incX,
69045768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                        const sp<Allocation>& Y, int incY, const sp<Allocation>& A) {
69149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (!A->getType()->getElement()->isCompatible(e) ||
69249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !X->getType()->getElement()->isCompatible(e) ||
69349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !Y->getType()->getElement()->isCompatible(e) ) {
69449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
69549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
69649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
69749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (X->getType()->getY() > 1 || Y->getType()->getY() > 1) {
69849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "BLAS vectors must have Y dimension of 0 or 1");
69949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
70049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
70149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = A->getType()->getY();
70249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
70349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
70449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (N < 1 || M < 1) {
70549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "M and N must be 1 or greater for GER");
70649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
70749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (incX <= 0 || incY <= 0) {
70849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Vector increments must be greater than 0");
70949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
71049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int expectedXDim = 1 + (M - 1) * incX;
71149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)X->getType()->getX() != expectedXDim) {
71249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Incorrect vector dimensions for GER");
71349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
71449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int expectedYDim = 1 + (N - 1) * incY;
71549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)Y->getType()->getX() != expectedYDim) {
71649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Incorrect vector dimensions for GER");
71749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
71849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
71949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
72049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
72145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic int validateSYR(RS* mRS, const sp<const Element>& e, RsBlasUplo Uplo,
72245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                       const sp<Allocation>& X, int incX, const sp<Allocation>& A) {
72349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (!A->getType()->getElement()->isCompatible(e) ||
72449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !X->getType()->getElement()->isCompatible(e)) {
72549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
72649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
72749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
72849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
72949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
73049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (X->getType()->getY() > 1) {
73149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "BLAS vectors must have Y dimension of 0 or 1");
73249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
73349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (N != (int)A->getType()->getY()) {
73449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "A must be a symmetric matrix");
73549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
73649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (incX <= 0) {
73749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Vector increments must be greater than 0");
73849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
73949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int expectedXDim = 1 + (N - 1) * incX;
74049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)X->getType()->getX() != expectedXDim) {
74149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Incorrect vector dimensions for SYR");
74249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
74349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    return N;
74449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
74545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic int validateSPR(RS* mRS, const sp<const Element>& e, RsBlasUplo Uplo,
74645768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                       const sp<Allocation>& X, int incX, const sp<Allocation>& Ap) {
74749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (!Ap->getType()->getElement()->isCompatible(e) ||
74849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !X->getType()->getElement()->isCompatible(e)) {
74949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
75049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
75149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (X->getType()->getY() > 1) {
75249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "BLAS vectors must have Y dimension of 0 or 1");
75349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
75449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
75549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Ap->getType()->getY() > 1) {
75649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Ap must have a Y dimension of 0 or 1");
75749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
75849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
75949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = sqrt((double)Ap->getType()->getX() * 2);
76049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)Ap->getType()->getX() != ((N * (N+1)) / 2)) {
76149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid dimension for Ap");
76249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
76349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (incX <= 0) {
76449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Vector increments must be greater than 0");
76549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
76649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int expectedXDim = 1 + (N - 1) * incX;
76749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)X->getType()->getX() != expectedXDim) {
76849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Incorrect vector dimensions for SPR");
76949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
77049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
77149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    return N;
77249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
77349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
77445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic int validateSYR2(RS* mRS, const sp<const Element>& e, RsBlasUplo Uplo, const sp<Allocation>& X,
77545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                        int incX, const sp<Allocation>& Y, int incY, const sp<Allocation>& A) {
77649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (!A->getType()->getElement()->isCompatible(e) ||
77749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !X->getType()->getElement()->isCompatible(e) ||
77849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !Y->getType()->getElement()->isCompatible(e)) {
77949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
78049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
78149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
78249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (X->getType()->getY() > 1 || Y->getType()->getY() > 1) {
78349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "BLAS vectors must have Y dimension of 0 or 1");
78449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
78549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
78649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
78749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
78849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (N != (int)A->getType()->getY()) {
78949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "A must be a symmetric matrix");
79049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
79149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (incX <= 0 || incY <= 0) {
79249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Vector increments must be greater than 0");
79349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
79449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int expectedXDim = 1 + (N - 1) * incX;
79549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int expectedYDim = 1 + (N - 1) * incY;
79649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)X->getType()->getX() != expectedXDim || (int)Y->getType()->getX() != expectedYDim) {
79749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Incorrect vector dimensions for SYR");
79849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
79949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    return N;
80049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
80149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
80245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic int validateSPR2(RS* mRS, const sp<const Element>& e, RsBlasUplo Uplo, const sp<Allocation>& X,
80345768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                        int incX, const sp<Allocation>& Y, int incY, const sp<Allocation>& Ap) {
80449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (!Ap->getType()->getElement()->isCompatible(e) ||
80549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !X->getType()->getElement()->isCompatible(e) ||
80649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !Y->getType()->getElement()->isCompatible(e)) {
80749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
80849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
80949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (X->getType()->getY() > 1 || Y->getType()->getY() > 1) {
81049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "BLAS vectors must have Y dimension of 0 or 1");
81149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
81249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
81349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Ap->getType()->getY() > 1) {
81449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Ap must have a Y dimension of 0 or 1");
81549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
81649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
81749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = sqrt((double)Ap->getType()->getX() * 2);
81849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)Ap->getType()->getX() != ((N * (N+1)) / 2)) {
81949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid dimension for Ap");
82049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
82149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (incX <= 0 || incY <= 0) {
82249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Vector increments must be greater than 0");
82349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
82449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int expectedXDim = 1 + (N - 1) * incX;
82549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int expectedYDim = 1 + (N - 1) * incY;
82649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)X->getType()->getX() != expectedXDim || (int)Y->getType()->getX() != expectedYDim) {
82749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Incorrect vector dimensions for SPR2");
82849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
82949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
83049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    return N;
83149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
83249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
83345768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::SSYMV(RsBlasUplo Uplo, float alpha, const sp<Allocation>& A, const sp<Allocation>& X,
83445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int incX, float beta, const sp<Allocation>& Y, int incY) {
83549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSYMV(mRS, Element::F32(mRS), Uplo, A, X, Y, incX, incY);
83649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_ssymv,
83749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, 0, Uplo, 0, 0, N, 0, alpha,
83849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                A->getID(), X->getID(), beta, Y->getID(), incX, incY, 0, 0);
83949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
84049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
84145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::SSBMV(RsBlasUplo Uplo, int K, float alpha, const sp<Allocation>& A, const sp<Allocation>& X,
84245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int incX, float beta, const sp<Allocation>& Y, int incY) {
84349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // SBMV is the same as SYMV + K >= 0
84449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (K < 0) {
84549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "K must be greater than or equal to 0");
84649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
84749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSYMV(mRS, Element::F32(mRS), Uplo, A, X, Y, incX, incY);
84849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_ssbmv,
84949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, 0, Uplo, 0, 0, N, K, alpha,
85049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                A->getID(), X->getID(), beta, Y->getID(), incX, incY, 0, 0);
85149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
85249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
85345768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::SSPMV(RsBlasUplo Uplo, float alpha, const sp<Allocation>& Ap, const sp<Allocation>& X,
85445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int incX, float beta, const sp<Allocation>& Y, int incY) {
85549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSPMV(mRS, Element::F32(mRS), Uplo, Ap, X, incX, Y, incY);
85649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_sspmv,
85749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, 0, Uplo, 0, 0, N, 0, alpha,
85849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                Ap->getID(), X->getID(), beta, Y->getID(), incX, incY, 0, 0);
85949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
86049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
86145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::SGER(float alpha, const sp<Allocation>& X, int incX,
86245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                               const sp<Allocation>& Y, int incY, const sp<Allocation>& A) {
86349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = A->getType()->getY();
86449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
86549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateGER(mRS, Element::F32(mRS), X, incX, Y, incY, A);
86649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_sger,
86749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, 0, 0, 0, M, N, 0, alpha,
86849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                X->getID(), Y->getID(), 0.f, A->getID(), incX, incY, 0, 0);
86949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
87049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
87145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::SSYR(RsBlasUplo Uplo, float alpha, const sp<Allocation>& X,
87245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                               int incX, const sp<Allocation>& A) {
87349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSYR(mRS, Element::F32(mRS), Uplo, X, incX, A);
87449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_ssyr,
87549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, 0, Uplo, 0, 0, N, 0, alpha,
87649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                X->getID(), A->getID(), 0.f, 0, incX, 0, 0, 0);
87749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
87849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
87945768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::SSPR(RsBlasUplo Uplo, float alpha, const sp<Allocation>& X,
88045768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                               int incX, const sp<Allocation>& Ap) {
88149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSPR(mRS, Element::F32(mRS), Uplo, X, incX, Ap);
88249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_sspr,
88349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, 0, Uplo, 0, 0, N, 0,
88449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                alpha, X->getID(), Ap->getID(), 0.f, 0, incX, 0, 0, 0);
88549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
88649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
88745768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::SSYR2(RsBlasUplo Uplo, float alpha, const sp<Allocation>& X, int incX,
88845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Y, int incY, const sp<Allocation>& A) {
88949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSYR2(mRS, Element::F32(mRS), Uplo, X, incX, Y, incY, A);
89049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_ssyr2,
89149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, 0, Uplo, 0, 0, N, 0, alpha,
89249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                X->getID(), Y->getID(), 0, A->getID(), incX, incY, 0, 0);
89349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
89449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
89545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::SSPR2(RsBlasUplo Uplo, float alpha, const sp<Allocation>& X, int incX,
89645768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Y, int incY, const sp<Allocation>& Ap) {
89749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSPR2(mRS, Element::F32(mRS), Uplo, X, incX, Y, incY, Ap);
89849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_sspr2,
89949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, 0, Uplo, 0, 0, N, 0, alpha,
90049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                X->getID(), Y->getID(), 0, Ap->getID(), incX, incY, 0, 0);
90149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
90249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
90345768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::DSYMV(RsBlasUplo Uplo, double alpha, const sp<Allocation>& A, const sp<Allocation>& X,
90445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int incX, double beta, const sp<Allocation>& Y, int incY) {
90549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSYMV(mRS, Element::F64(mRS), Uplo, A, X, Y, incX, incY);
90649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dsymv,
90749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, 0, Uplo, 0, 0, N, 0, alpha,
90849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                A->getID(), X->getID(), beta, Y->getID(), incX, incY, 0, 0);
90949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
91049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
91145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::DSBMV(RsBlasUplo Uplo, int K, double alpha, const sp<Allocation>& A, const sp<Allocation>& X,
91245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int incX, double beta, const sp<Allocation>& Y, int incY) {
91349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // SBMV is the same as SYMV + K >= 0
91449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (K < 0) {
91549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "K must be greater than or equal to 0");
91649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
91749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSYMV(mRS, Element::F64(mRS), Uplo, A, X, Y, incX, incY);
91849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dsbmv,
91949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, 0, Uplo, 0, 0, N, K, alpha,
92049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                A->getID(), X->getID(), beta, Y->getID(), incX, incY, 0, 0);
92149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
92249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
92345768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::DSPMV(RsBlasUplo Uplo, double alpha, const sp<Allocation>& Ap, const sp<Allocation>& X,
92445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int incX, double beta, const sp<Allocation>& Y, int incY) {
92549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSPMV(mRS, Element::F64(mRS), Uplo, Ap, X, incX, Y, incY);
92649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dspmv,
92749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, 0, Uplo, 0, 0, N, 0, alpha,
92849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                Ap->getID(), X->getID(), beta, Y->getID(), incX, incY, 0, 0);
92949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
93049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
93145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::DGER(double alpha, const sp<Allocation>& X, int incX, const sp<Allocation>& Y,
93245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                               int incY, const sp<Allocation>& A) {
93349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = A->getType()->getY();
93449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
93549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateGER(mRS, Element::F64(mRS), X, incX, Y, incY, A);
93649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dger,
93749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, 0, 0, 0, M, N, 0, alpha,
93849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                X->getID(), Y->getID(), 0.f, A->getID(), incX, incY, 0, 0);
93949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
94049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
94145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::DSYR(RsBlasUplo Uplo, double alpha, const sp<Allocation>& X,
94245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                               int incX, const sp<Allocation>& A) {
94349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSYR(mRS, Element::F64(mRS), Uplo, X, incX, A);
94449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dsyr,
94549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, 0, Uplo, 0, 0, N, 0, alpha,
94649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                X->getID(), A->getID(), 0.f, 0, incX, 0, 0, 0);
94749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
94849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
94945768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::DSPR(RsBlasUplo Uplo, double alpha, const sp<Allocation>& X,
95045768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                               int incX, const sp<Allocation>& Ap) {
95149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSPR(mRS, Element::F64(mRS), Uplo, X, incX, Ap);
95249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dspr,
95349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, 0, Uplo, 0, 0, N, 0, alpha,
95449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                X->getID(), Ap->getID(), 0.f, 0, incX, 0, 0, 0);
95549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
95649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
95745768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::DSYR2(RsBlasUplo Uplo, double alpha, const sp<Allocation>& X, int incX,
95845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Y, int incY, const sp<Allocation>& A) {
95949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSYR2(mRS, Element::F64(mRS), Uplo, X, incX, Y, incY, A);
96049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dsyr2,
96149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, 0, Uplo, 0, 0, N, 0, alpha,
96249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                X->getID(), Y->getID(), 0, A->getID(), incX, incY, 0, 0);
96349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
96449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
96545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::DSPR2(RsBlasUplo Uplo, double alpha, const sp<Allocation>& X, int incX,
96645768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Y, int incY, const sp<Allocation>& Ap) {
96749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSPR2(mRS, Element::F64(mRS), Uplo, X, incX, Y, incY, Ap);
96849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dspr2,
96949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, 0, Uplo, 0, 0, N, 0, alpha,
97049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                X->getID(), Y->getID(), 0, Ap->getID(), incX, incY, 0, 0);
97149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
97249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
97349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
97449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang/**
97549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang * Level 2, C and Z only
97649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang */
97749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
97845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic void validateGERU(RS* mRS, const sp<const Element>& e, const sp<Allocation>& X, int incX,
97945768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                         const sp<Allocation>& Y, int incY, const sp<Allocation>& A) {
98049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (!A->getType()->getElement()->isCompatible(e) ||
98149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !X->getType()->getElement()->isCompatible(e) ||
98249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !Y->getType()->getElement()->isCompatible(e)) {
98349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
98449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
98549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (X->getType()->getY() > 1 || Y->getType()->getY() > 1) {
98649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "BLAS vectors must have Y dimension of 0 or 1");
98749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
98849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
98949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = A->getType()->getY();
99049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
99149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (incX <= 0 || incY <= 0) {
99249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Vector increments must be greater than 0");
99349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
99449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int expectedXDim = 1 + (M - 1) * incX;
99549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)X->getType()->getX() != expectedXDim) {
99649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Incorrect vector dimensions for GERU");
99749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
99849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int expectedYDim = 1 + (N - 1) * incY;
99949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)Y->getType()->getX() != expectedYDim) {
100049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Incorrect vector dimensions for GERU");
100149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
100249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
100349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
100449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
100545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::CHEMV(RsBlasUplo Uplo, Float2 alpha, const sp<Allocation>& A,
100645768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& X, int incX, Float2 beta, const sp<Allocation>& Y, int incY) {
100749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // HEMV is the same as SYR2 validation-wise
100849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSYR2(mRS, Element::F32_2(mRS), Uplo, X, incX, Y, incY, A);
100949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_chemv,
101049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, 0, Uplo, 0, 0, N, 0,
101149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha.x, alpha.y, A->getID(), X->getID(),
101249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 beta.x, beta.y, Y->getID(), incX, incY, 0, 0);
101349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
101449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
101545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::CHBMV(RsBlasUplo Uplo, int K, Float2 alpha, const sp<Allocation>& A,
101645768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& X, int incX, Float2 beta, const sp<Allocation>& Y, int incY) {
101749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // HBMV is the same as SYR2 validation-wise
101849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSYR2(mRS, Element::F32_2(mRS), Uplo, X, incX, Y, incY, A);
101949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (K < 0) {
102049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "K must be 0 or greater for HBMV");
102149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
102249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_chbmv,
102349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, 0, Uplo, 0, 0, N, K,
102449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha.x, alpha.y, A->getID(), X->getID(),
102549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 beta.x, beta.y, Y->getID(), incX, incY, 0, 0);
102649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
102749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
102845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::CHPMV(RsBlasUplo Uplo, Float2 alpha, const sp<Allocation>& Ap,
102945768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& X, int incX, Float2 beta, const sp<Allocation>& Y, int incY) {
103049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // HPMV is the same as SPR2
103149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSPR2(mRS, Element::F32_2(mRS), Uplo, X, incX, Y, incY, Ap);
103249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_chpmv,
103349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, 0, Uplo, 0, 0, N, 0,
103449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha.x, alpha.y, Ap->getID(), X->getID(),
103549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 beta.x, beta.y, Y->getID(), incX, incY, 0, 0);
103649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
103749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
103845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::CGERU(Float2 alpha, const sp<Allocation>& X, int incX,
103945768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Y, int incY, const sp<Allocation>& A) {
104049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateGERU(mRS, Element::F32_2(mRS), X, incX, Y, incY, A);
104149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = A->getType()->getY();
104249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
104349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_cgeru,
104449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, 0, 0, 0, M, N, 0,
104549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha.x, alpha.y, X->getID(), Y->getID(),
104649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, A->getID(), incX, incY, 0, 0);
104749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
104849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
104945768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::CGERC(Float2 alpha, const sp<Allocation>& X, int incX,
105045768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Y, int incY, const sp<Allocation>& A) {
105149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // Same as GERU
105249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateGERU(mRS, Element::F32_2(mRS), X, incX, Y, incY, A);
105349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = A->getType()->getY();
105449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
105549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_cgerc,
105649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, 0, 0, 0, M, N, 0,
105749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha.x, alpha.y, X->getID(), Y->getID(),
105849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, A->getID(), incX, incY, 0, 0);
105949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
106049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
106145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::CHER(RsBlasUplo Uplo, float alpha, const sp<Allocation>& X,
106245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                               int incX, const sp<Allocation>& A) {
106349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // Same as SYR
106449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSYR(mRS, Element::F32_2(mRS), Uplo, X, incX, A);
106549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_cher,
106649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, 0, Uplo, 0, 0, N, 0,
106749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha, 0, X->getID(), 0,
106849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, A->getID(), incX, 0, 0, 0);
106949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
107049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
107145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::CHPR(RsBlasUplo Uplo, float alpha, const sp<Allocation>& X,
107245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                               int incX, const sp<Allocation>& Ap) {
107349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // Equivalent to SPR for validation
107449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSPR(mRS, Element::F32_2(mRS), Uplo, X, incX, Ap);
107549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_chpr,
107649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, 0, Uplo, 0, 0, N, 0,
107749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha, 0, X->getID(), 0,
107849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, Ap->getID(), incX, 0, 0, 0);
107949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
108049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
108145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::CHER2(RsBlasUplo Uplo, Float2 alpha, const sp<Allocation>& X, int incX,
108245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Y, int incY, const sp<Allocation>& A) {
108349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // Same as SYR2
108449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSYR2(mRS, Element::F32_2(mRS), Uplo, X, incX, Y, incY, A);
108549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_cher2,
108649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, 0, Uplo, 0, 0, N, 0,
108749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha.x, alpha.y, X->getID(), Y->getID(),
108849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, A->getID(), incX, incY, 0, 0);
108949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
109049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
109145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::CHPR2(RsBlasUplo Uplo, Float2 alpha, const sp<Allocation>& X, int incX,
109245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Y, int incY, const sp<Allocation>& Ap) {
109349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // Same as SPR2
109449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSPR2(mRS, Element::F32_2(mRS), Uplo, X, incX, Y, incY, Ap);
109549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_chpr2,
109649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, 0, Uplo, 0, 0, N, 0,
109749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha.x, alpha.y, X->getID(), Y->getID(),
109849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, Ap->getID(), incX, incY, 0, 0);
109949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
110049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
110145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::ZHEMV(RsBlasUplo Uplo, Double2 alpha, const sp<Allocation>& A,
110245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& X, int incX, Double2 beta, const sp<Allocation>& Y, int incY) {
110349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // HEMV is the same as SYR2 validation-wise
110449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSYR2(mRS, Element::F64_2(mRS), Uplo, X, incX, Y, incY, A);
110549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zhemv,
110649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           0, 0, 0, Uplo, 0, 0, N, 0,
110749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha.x, alpha.y, A->getID(), X->getID(),
110849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           beta.x, beta.y, Y->getID(), incX, incY, 0, 0);
110949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
111049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
111145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::ZHBMV(RsBlasUplo Uplo, int K, Double2 alpha, const sp<Allocation>& A, const sp<Allocation>& X,
111245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int incX, Double2 beta, const sp<Allocation>& Y, int incY) {
111349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // HBMV is the same as SYR2 validation-wise
111449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSYR2(mRS, Element::F64_2(mRS), Uplo, X, incX, Y, incY, A);
111549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (K < 0) {
111649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "K must be 0 or greater for HBMV");
111749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
111849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zhbmv,
111949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           0, 0, 0, Uplo, 0, 0, N, K,
112049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha.x, alpha.y, A->getID(), X->getID(),
112149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           beta.x, beta.y, Y->getID(), incX, incY, 0, 0);
112249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
112349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
112445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::ZHPMV(RsBlasUplo Uplo, Double2 alpha, const sp<Allocation>& Ap, const sp<Allocation>& X,
112545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                int incX, Double2 beta, const sp<Allocation>& Y, int incY) {
112649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // HPMV is the same as SPR2
112749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSPR2(mRS, Element::F64_2(mRS), Uplo, X, incX, Y, incY, Ap);
112849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zhpmv,
112949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           0, 0, 0, Uplo, 0, 0, N, 0,
113049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha.x, alpha.y, Ap->getID(), X->getID(),
113149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           beta.x, beta.y, Y->getID(), incX, incY, 0, 0);
113249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
113349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
113445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::ZGERU(Double2 alpha, const sp<Allocation>& X, int incX,
113545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Y, int incY, const sp<Allocation>& A) {
113649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateGERU(mRS, Element::F64_2(mRS), X, incX, Y, incY, A);
113749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = A->getType()->getY();
113849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
113949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zgeru,
114049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           0, 0, 0, 0, 0, M, N, 0,
114149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha.x, alpha.y, X->getID(), Y->getID(),
114249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           0, 0, A->getID(), incX, incY, 0, 0);
114349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
114449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
114545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::ZGERC(Double2 alpha, const sp<Allocation>& X, int incX,
114645768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Y, int incY, const sp<Allocation>& A) {
114749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // Same as GERU
114849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateGERU(mRS, Element::F64_2(mRS), X, incX, Y, incY, A);
114949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = A->getType()->getY();
115049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = A->getType()->getX();
115149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zgerc,
115249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           0, 0, 0, 0, 0, M, N, 0,
115349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha.x, alpha.y, X->getID(), Y->getID(),
115449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           0, 0, A->getID(), incX, incY, 0, 0);
115549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
115649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
115745768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::ZHER(RsBlasUplo Uplo, double alpha, const sp<Allocation>& X,
115845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                               int incX, const sp<Allocation>& A) {
115949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // Same as SYR
116049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSYR(mRS, Element::F64_2(mRS), Uplo, X, incX, A);
116149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zher,
116249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           0, 0, 0, Uplo, 0, 0, N, 0,
116349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha, 0, X->getID(), 0,
116449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           0, 0, A->getID(), incX, 0, 0, 0);
116549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
116649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
116745768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::ZHPR(RsBlasUplo Uplo, double alpha, const sp<Allocation>& X,
116845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                               int incX, const sp<Allocation>& Ap) {
116949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // Equivalent to SPR for validation
117049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSPR(mRS, Element::F64_2(mRS), Uplo, X, incX, Ap);
117149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zhpr,
117249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           0, 0, 0, Uplo, 0, 0, N, 0,
117349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha, 0, X->getID(), 0,
117449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           0, 0, Ap->getID(), incX, 0, 0, 0);
117549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
117649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
117745768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::ZHER2(RsBlasUplo Uplo, Double2 alpha, const sp<Allocation>& X, int incX,
117845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Y, int incY, const sp<Allocation>& A) {
117949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // Same as SYR2
118049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSYR2(mRS, Element::F64_2(mRS), Uplo, X, incX, Y, incY, A);
118149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zher2,
118249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           0, 0, 0, Uplo, 0, 0, N, 0,
118349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha.x, alpha.y, X->getID(), Y->getID(),
118449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           0, 0, A->getID(), incX, incY, 0, 0);
118549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
118649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
118745768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::ZHPR2(RsBlasUplo Uplo, Double2 alpha, const sp<Allocation>& X, int incX,
118845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& Y, int incY, const sp<Allocation>& Ap) {
118949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // Same as SPR2
119049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int N = validateSPR2(mRS, Element::F64_2(mRS), Uplo, X, incX, Y, incY, Ap);
119149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zhpr2,
119249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           0, 0, 0, Uplo, 0, 0, N, 0,
119349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha.x, alpha.y, X->getID(), Y->getID(),
119449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           0, 0, Ap->getID(), incX, incY, 0, 0);
119549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
119649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
119749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
119849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang/**
119949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang * Level 3 BLAS
120049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang */
120149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
120245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic void validateL3(RS* mRS, const sp<const Element>& e, int TransA, int TransB, int Side,
120345768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                       const sp<Allocation>& A, const sp<Allocation>& B, const sp<Allocation>& C) {
120449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int aM = -1, aN = -1, bM = -1, bN = -1, cM = -1, cN = -1;
120549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((A != nullptr && !A->getType()->getElement()->isCompatible(e)) ||
120649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        (B != nullptr && !B->getType()->getElement()->isCompatible(e)) ||
120749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        (C != nullptr && !C->getType()->getElement()->isCompatible(e))) {
120849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
120949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
121049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (C == nullptr) {
121149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        // Since matrix C is used to store the result, it cannot be null.
121249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Allocation C cannot be null");
121349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
121449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    cM = C->getType()->getY();
121549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    cN = C->getType()->getX();
121649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
121749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Side == RsBlasRight) {
121849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        if ((A == nullptr && B != nullptr) || (A != nullptr && B == nullptr)) {
121949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Provided Matrix A without Matrix B, or vice versa");
122049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        }
122149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        if (B != nullptr) {
122249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            bM = A->getType()->getY();
122349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            bN = A->getType()->getX();
122449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        }
122549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        if (A != nullptr) {
122649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            aM = B->getType()->getY();
122749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            aN = B->getType()->getX();
122849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        }
122949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
123049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        if (A != nullptr) {
123149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            if (TransA == RsBlasTrans || TransA == RsBlasConjTrans) {
123249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                aN = A->getType()->getY();
123349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                aM = A->getType()->getX();
123449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            } else {
123549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                aM = A->getType()->getY();
123649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                aN = A->getType()->getX();
123749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            }
123849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        }
123949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        if (B != nullptr) {
124049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            if (TransB == RsBlasTrans || TransB == RsBlasConjTrans) {
124149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                bN = B->getType()->getY();
124249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                bM = B->getType()->getX();
124349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            } else {
124449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                bM = B->getType()->getY();
124549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                bN = B->getType()->getX();
124649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            }
124749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        }
124849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
124949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (A != nullptr && B != nullptr && C != nullptr) {
125049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        if (aN != bM || aM != cM || bN != cN) {
125149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called BLAS with invalid dimensions");
125249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        }
125349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else if (A != nullptr && C != nullptr) {
125449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        // A and C only, for SYRK
125549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        if (cM != cN) {
125649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Matrix C is not symmetric");
125749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        }
125849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        if (aM != cM) {
125949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called BLAS with invalid dimensions");
126049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        }
126149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else if (A != nullptr && B != nullptr) {
126249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        // A and B only
126349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        if (aN != bM) {
126449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called BLAS with invalid dimensions");
126549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        }
126649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
126749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
126849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
126949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
127049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::SGEMM(RsBlasTranspose TransA, RsBlasTranspose TransB, float alpha,
127145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, const sp<Allocation>& B, float beta, const sp<Allocation>& C) {
127249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateL3(mRS, Element::F32(mRS), TransA, TransB, 0, A, B, C);
127349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
127449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = -1, N = -1, K = -1;
127549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (TransA != RsBlasNoTrans) {
127649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        M = A->getType()->getX();
127749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getY();
127849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
127949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        M = A->getType()->getY();
128049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getX();
128149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
128249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (TransB != RsBlasNoTrans) {
128349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        N = B->getType()->getY();
128449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
128549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        N = B->getType()->getX();
128649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
128749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_sgemm,
128849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, TransB, 0, 0, 0, M, N, K,
128949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                alpha, A->getID(), B->getID(),
129049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                beta, C->getID(), 0, 0, 0, 0);
129149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
129249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
129349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::DGEMM(RsBlasTranspose TransA, RsBlasTranspose TransB, double alpha,
129445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, const sp<Allocation>& B, double beta, const sp<Allocation>& C) {
129549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateL3(mRS, Element::F64(mRS), TransA, TransB, 0, A, B, C);
129649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = -1, N = -1, K = -1;
129749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (TransA != RsBlasNoTrans) {
129849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        M = A->getType()->getX();
129949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getY();
130049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
130149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        M = A->getType()->getY();
130249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getX();
130349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
130449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (TransB != RsBlasNoTrans) {
130549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        N = B->getType()->getY();
130649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
130749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        N = B->getType()->getX();
130849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
130949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dgemm,
131049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, TransB, 0, 0, 0, M, N, K,
131149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                alpha, A->getID(), B->getID(),
131249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                beta, C->getID(), 0, 0, 0, 0);
131349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
131449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
131549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::CGEMM(RsBlasTranspose TransA, RsBlasTranspose TransB, Float2 alpha,
131645768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, const sp<Allocation>& B, Float2 beta, const sp<Allocation>& C) {
131749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateL3(mRS, Element::F32_2(mRS), TransA, TransB, 0, A, B, C);
131849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = -1, N = -1, K = -1;
131949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (TransA != RsBlasNoTrans) {
132049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        M = A->getType()->getX();
132149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getY();
132249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
132349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        M = A->getType()->getY();
132449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getX();
132549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
132649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (TransB != RsBlasNoTrans) {
132749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        N = B->getType()->getY();
132849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
132949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        N = B->getType()->getX();
133049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
133149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_cgemm,
133249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 TransA, TransB, 0, 0, 0, M, N, K,
133349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha.x, alpha.y, A->getID(), B->getID(),
133449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 beta.x, beta.y, C->getID(), 0, 0, 0, 0);
133549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
133649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
133749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::ZGEMM(RsBlasTranspose TransA, RsBlasTranspose TransB, Double2 alpha,
133845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, const sp<Allocation>& B, Double2 beta, const sp<Allocation>& C) {
133949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateL3(mRS, Element::F64_2(mRS), TransA, TransB, 0, A, B, C);
134049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = -1, N = -1, K = -1;
134149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (TransA != RsBlasNoTrans) {
134249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        M = A->getType()->getX();
134349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getY();
134449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
134549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        M = A->getType()->getY();
134649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getX();
134749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
134849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (TransB != RsBlasNoTrans) {
134949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        N = B->getType()->getY();
135049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
135149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        N = B->getType()->getX();
135249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
135349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zgemm,
135449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           TransA, TransB, 0, 0, 0, M, N, K,
135549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha.x, alpha.y, A->getID(), B->getID(),
135649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           beta.x, beta.y, C->getID(), 0, 0, 0, 0);
135749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
135849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
135949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::SSYMM(RsBlasSide Side, RsBlasUplo Uplo, float alpha,
136045768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, const sp<Allocation>& B, float beta, const sp<Allocation>& C) {
136149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    //For SYMM, Matrix A should be symmetric
136249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (A->getType()->getX() != A->getType()->getY()) {
136349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Matrix A is not symmetric");
136449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
136549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateL3(mRS, Element::F32(mRS), 0, 0, Side, A, B, C);
136649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_ssymm,
136749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, Side, Uplo, 0, C->getType()->getY(), C->getType()->getX(), 0,
136849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                alpha, A->getID(), B->getID(),
136949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                beta, C->getID(), 0, 0, 0, 0);
137049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
137149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
137249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::DSYMM(RsBlasSide Side, RsBlasUplo Uplo, double alpha,
137345768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, const sp<Allocation>& B, double beta, const sp<Allocation>& C) {
137449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (A->getType()->getX() != A->getType()->getY()) {
137549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Matrix A is not symmetric");
137649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
137749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateL3(mRS, Element::F64(mRS), 0, 0, Side, A, B, C);
137849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dsymm,
137949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                0, 0, Side, Uplo, 0, C->getType()->getY(), C->getType()->getX(), 0,
138049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                alpha, A->getID(), B->getID(),
138149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                beta, C->getID(), 0, 0, 0, 0);
138249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
138349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
138449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::CSYMM(RsBlasSide Side, RsBlasUplo Uplo, Float2 alpha,
138545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, const sp<Allocation>& B, Float2 beta, const sp<Allocation>& C) {
138649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (A->getType()->getX() != A->getType()->getY()) {
138749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Matrix A is not symmetric");
138849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
138949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateL3(mRS, Element::F32_2(mRS), 0, 0, Side, A, B, C);
139049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_csymm,
139149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, Side, Uplo, 0, C->getType()->getY(), C->getType()->getX(), 0,
139249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha.x, alpha.y, A->getID(), B->getID(),
139349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 beta.x, beta.y, C->getID(), 0, 0, 0, 0);
139449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
139549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
139649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::ZSYMM(RsBlasSide Side, RsBlasUplo Uplo, Double2 alpha,
139745768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, const sp<Allocation>& B, Double2 beta, const sp<Allocation>& C) {
139849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (A->getType()->getX() != A->getType()->getY()) {
139949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Matrix A is not symmetric");
140049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
140149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateL3(mRS, Element::F64_2(mRS), 0, 0, Side, A, B, C);
140249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zsymm,
140349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           0, 0, Side, Uplo, 0, C->getType()->getY(), C->getType()->getX(), 0,
140449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha.x, alpha.y, A->getID(), B->getID(),
140549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           beta.x, beta.y, C->getID(), 0, 0, 0, 0);
140649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
140749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
140849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::SSYRK(RsBlasUplo Uplo, RsBlasTranspose Trans, float alpha,
140945768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, float beta, const sp<Allocation>& C) {
141049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateL3(mRS, Element::F32(mRS), Trans, 0, 0, A, nullptr, C);
141149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int K = -1;
141249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Trans != RsBlasNoTrans) {
141349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getY();
141449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
141549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getX();
141649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
141749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_ssyrk,
141849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                Trans, 0, 0, Uplo, 0, 0, C->getType()->getX(), K,
141949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                alpha, A->getID(), 0,
142049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                beta, C->getID(), 0, 0, 0, 0);
142149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
142249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
142349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::DSYRK(RsBlasUplo Uplo, RsBlasTranspose Trans, double alpha,
142445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, double beta, const sp<Allocation>& C) {
142549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateL3(mRS, Element::F64(mRS), Trans, 0, 0, A, nullptr, C);
142649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int K = -1;
142749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Trans != RsBlasNoTrans) {
142849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getY();
142949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
143049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getX();
143149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
143249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dsyrk,
143349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                Trans, 0, 0, Uplo, 0, 0, C->getType()->getX(), K,
143449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                alpha, A->getID(), 0,
143549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                beta, C->getID(), 0, 0, 0, 0);
143649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
143749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
143849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::CSYRK(RsBlasUplo Uplo, RsBlasTranspose Trans, Float2 alpha,
143945768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, Float2 beta, const sp<Allocation>& C) {
144049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateL3(mRS, Element::F32_2(mRS), Trans, 0, 0, A, nullptr, C);
144149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int K = -1;
144249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Trans != RsBlasNoTrans) {
144349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getY();
144449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
144549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getX();
144649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
144749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_csyrk,
144849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 Trans, 0, 0, Uplo, 0, 0, C->getType()->getX(), K,
144949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha.x, alpha.y, A->getID(), 0,
145049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 beta.x, beta.y, C->getID(), 0, 0, 0, 0);
145149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
145249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
145349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::ZSYRK(RsBlasUplo Uplo, RsBlasTranspose Trans, Double2 alpha,
145445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, Double2 beta, const sp<Allocation>& C) {
145549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateL3(mRS, Element::F64_2(mRS), Trans, 0, 0, A, nullptr, C);
145649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int K = -1;
145749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Trans != RsBlasNoTrans) {
145849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getY();
145949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
146049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getX();
146149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
146249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zsyrk,
146349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           Trans, 0, 0, Uplo, 0, 0, C->getType()->getX(), K,
146449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha.x, alpha.y, A->getID(), 0,
146549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           beta.x, beta.y, C->getID(), 0, 0, 0, 0);
146649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
146749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
146845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic void validateSYR2K(RS* mRS, const sp<const Element>& e, RsBlasTranspose Trans,
146945768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                          const sp<Allocation>& A, const sp<Allocation>& B, const sp<Allocation>& C) {
147049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (!A->getType()->getElement()->isCompatible(e) ||
147149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !B->getType()->getElement()->isCompatible(e) ||
147249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !C->getType()->getElement()->isCompatible(e)) {
147349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
147449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
147549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int Cdim = -1;
147649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // A is n x k if no transpose, k x n if transpose
147749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // C is n x n
147849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Trans == RsBlasTrans) {
147949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        // check columns versus C
148049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        Cdim = A->getType()->getX();
148149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
148249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        // check rows versus C
148349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        Cdim = A->getType()->getY();
148449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
148549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((int)C->getType()->getX() != Cdim || (int)C->getType()->getY() != Cdim) {
148649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid symmetric matrix in SYR2K");
148749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
148849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // A dims == B dims
148949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (A->getType()->getX() != B->getType()->getX() || A->getType()->getY() != B->getType()->getY()) {
149049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid A and B in SYR2K");
149149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
149249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
149349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
149449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::SSYR2K(RsBlasUplo Uplo, RsBlasTranspose Trans, float alpha,
149545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                 const sp<Allocation>& A, const sp<Allocation>& B, float beta, const sp<Allocation>& C) {
149649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateSYR2K(mRS, Element::F32(mRS), Trans, A, B, C);
149749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int K = -1;
149849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Trans != RsBlasNoTrans) {
149949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getY();
150049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
150149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getX();
150249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
150349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_ssyr2k,
150449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                Trans, 0, 0, Uplo, 0, 0, C->getType()->getX(), K,
150549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                alpha, A->getID(), B->getID(),
150649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                beta, C->getID(), 0, 0, 0, 0);
150749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
150849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
150949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::DSYR2K(RsBlasUplo Uplo, RsBlasTranspose Trans, double alpha,
151045768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                 const sp<Allocation>& A, const sp<Allocation>& B, double beta, const sp<Allocation>& C) {
151149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateSYR2K(mRS, Element::F64(mRS), Trans, A, B, C);
151249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int K = -1;
151349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Trans != RsBlasNoTrans) {
151449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getY();
151549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
151649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getX();
151749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
151849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dsyr2k,
151949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                Trans, 0, 0, Uplo, 0, 0, C->getType()->getX(), K,
152049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                alpha, A->getID(), B->getID(),
152149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                beta, C->getID(), 0, 0, 0, 0);
152249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
152349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
152449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::CSYR2K(RsBlasUplo Uplo, RsBlasTranspose Trans, Float2 alpha,
152545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                 const sp<Allocation>& A, const sp<Allocation>& B, Float2 beta, const sp<Allocation>& C) {
152649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateSYR2K(mRS, Element::F32_2(mRS), Trans, A, B, C);
152749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int K = -1;
152849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Trans != RsBlasNoTrans) {
152949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getY();
153049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
153149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getX();
153249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
153349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_csyr2k,
153449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 Trans, 0, 0, Uplo, 0, 0, C->getType()->getX(), K,
153549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha.x, alpha.y, A->getID(), B->getID(),
153649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 beta.x, beta.y, C->getID(), 0, 0, 0, 0);
153749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
153849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
153949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::ZSYR2K(RsBlasUplo Uplo, RsBlasTranspose Trans, Double2 alpha,
154045768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                 const sp<Allocation>& A, const sp<Allocation>& B, Double2 beta, const sp<Allocation>& C) {
154149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateSYR2K(mRS, Element::F64_2(mRS), Trans, A, B, C);
154249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int K = -1;
154349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Trans != RsBlasNoTrans) {
154449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getY();
154549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
154649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        K = A->getType()->getX();
154749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
154849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zsyr2k,
154949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           Trans, 0, 0, Uplo, 0, 0, C->getType()->getX(), K,
155049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha.x, alpha.y, A->getID(), B->getID(),
155149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           beta.x, beta.y, C->getID(), 0, 0, 0, 0);
155249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
155349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
155445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic void validateTRMM(RS* mRS, const sp<const Element>& e, RsBlasSide Side, RsBlasTranspose TransA,
155545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                         const sp<Allocation>& A, const sp<Allocation>& B) {
155649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int aM = -1, aN = -1, bM = -1, bN = -1;
155749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (!A->getType()->getElement()->isCompatible(e) ||
155849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !B->getType()->getElement()->isCompatible(e)) {
155949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
156049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
156149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
156249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    aM = A->getType()->getY();
156349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    aN = A->getType()->getX();
156449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (aM != aN) {
156549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called TRMM with a non-symmetric matrix A");
156649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
156749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
156849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    bM = B->getType()->getY();
156949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    bN = B->getType()->getX();
157049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Side == RsBlasLeft) {
157149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        if (aN != bM) {
157249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called TRMM with invalid matrices");
157349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        }
157449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
157549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        if (bN != aM) {
157649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called TRMM with invalid matrices");
157749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        }
157849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
157949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
158049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
158149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::STRMM(RsBlasSide Side, RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
158245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                float alpha, const sp<Allocation>& A, const sp<Allocation>& B) {
158349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMM(mRS, Element::F32(mRS), Side, TransA, A, B);
158449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_strmm,
158549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, Side, Uplo, Diag,\
158649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                B->getType()->getY(), B->getType()->getX(), 0,
158749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                alpha, A->getID(), B->getID(), 0.f, 0, 0, 0, 0, 0);
158849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
158949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
159049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::DTRMM(RsBlasSide Side, RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
159145768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                double alpha, const sp<Allocation>& A, const sp<Allocation>& B) {
159249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMM(mRS, Element::F64(mRS), Side, TransA, A, B);
159349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dtrmm,
159449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, Side, Uplo, Diag,
159549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                B->getType()->getY(), B->getType()->getX(), 0,
159649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                alpha, A->getID(), B->getID(), 0, 0, 0, 0, 0, 0);
159749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
159849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
159949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::CTRMM(RsBlasSide Side, RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
160045768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                Float2 alpha, const sp<Allocation>& A, const sp<Allocation>& B) {
160149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMM(mRS, Element::F32_2(mRS), Side, TransA, A, B);
160249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_ctrmm,
160349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 TransA, 0, Side, Uplo, Diag,
160449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 B->getType()->getY(), B->getType()->getX(), 0,
160549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha.x, alpha.y, A->getID(), B->getID(), 0, 0, 0, 0, 0, 0, 0);
160649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
160749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
160849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::ZTRMM(RsBlasSide Side, RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
160945768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                Double2 alpha, const sp<Allocation>& A, const sp<Allocation>& B) {
161049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRMM(mRS, Element::F64_2(mRS), Side, TransA, A, B);
161149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_ztrmm,
161249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           TransA, 0, Side, Uplo, Diag,
161349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           B->getType()->getY(), B->getType()->getX(), 0,
161449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha.x, alpha.y, A->getID(), B->getID(), 0, 0, 0, 0, 0, 0, 0);
161549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
161649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
161745768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic void validateTRSM(RS* mRS, const sp<const Element>& e, RsBlasSide Side, RsBlasTranspose TransA,
161845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                         const sp<Allocation>& A, const sp<Allocation>& B) {
161949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int adim = -1, bM = -1, bN = -1;
162049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (!A->getType()->getElement()->isCompatible(e) ||
162149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !B->getType()->getElement()->isCompatible(e)) {
162249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
162349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
162449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    adim = A->getType()->getX();
162549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (adim != (int)A->getType()->getY()) {
162649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        // This may be unnecessary, the restriction could potentially be relaxed.
162749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        // Allocation A needs to contain at least that symmetric matrix but could theoretically
162849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        // be larger for now we assume adapters are sufficient, will reevaluate in the future.
162949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called TRSM with a non-symmetric matrix A");
163049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
163149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    bM = B->getType()->getY();
163249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    bN = B->getType()->getX();
163349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Side == RsBlasLeft) {
163449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        // A is M*M
163549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        if (adim != bM) {
163649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called TRSM with invalid matrix dimensions");
163749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        }
163849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
163949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        // A is N*N
164049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        if (adim != bN) {
164149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called TRSM with invalid matrix dimensions");
164249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        }
164349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
164449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
164549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
164649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::STRSM(RsBlasSide Side, RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
164745768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                float alpha, const sp<Allocation>& A, const sp<Allocation>& B) {
164849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRSM(mRS, Element::F32(mRS), Side, TransA, A, B);
164949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Single(mRS, mRS->getContext(), getID(), RsBlas_strsm,
165049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, Side, Uplo, Diag,
165149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                B->getType()->getY(), B->getType()->getX(), 0,
165249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                alpha, A->getID(), B->getID(), 0, 0, 0, 0, 0, 0);
165349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
165449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
165549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::DTRSM(RsBlasSide Side, RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
165645768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                double alpha, const sp<Allocation>& A, const sp<Allocation>& B) {
165749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRSM(mRS, Element::F64(mRS), Side, TransA, A, B);
165849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Double(mRS, mRS->getContext(), getID(), RsBlas_dtrsm,
165949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                TransA, 0, Side, Uplo, Diag,
166049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                B->getType()->getY(), B->getType()->getX(), 0,
166149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                alpha, A->getID(), B->getID(), 0, 0, 0, 0, 0, 0);
166249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
166349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
166449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::CTRSM(RsBlasSide Side, RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
166545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                Float2 alpha, const sp<Allocation>& A, const sp<Allocation>& B) {
166649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRSM(mRS, Element::F32_2(mRS), Side, TransA, A, B);
166749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_ctrsm,
166849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 TransA, 0, Side, Uplo, Diag,
166949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 B->getType()->getY(), B->getType()->getX(), 0,
167049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha.x, alpha.y, A->getID(), B->getID(), 0, 0, 0, 0, 0, 0, 0);
167149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
167249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
167349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::ZTRSM(RsBlasSide Side, RsBlasUplo Uplo, RsBlasTranspose TransA, RsBlasDiag Diag,
167445768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                Double2 alpha, const sp<Allocation>& A, const sp<Allocation>& B) {
167549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateTRSM(mRS, Element::F64_2(mRS), Side, TransA, A, B);
167649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_ztrsm,
167749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           TransA, 0, Side, Uplo, Diag,
167849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           B->getType()->getY(), B->getType()->getX(), 0,
167949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha.x, alpha.y, A->getID(), B->getID(), 0, 0, 0, 0, 0, 0, 0);
168049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
168149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
168245768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic void validateHEMM(RS* mRS, const sp<const Element>& e, RsBlasSide Side,
168345768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                         const sp<Allocation>& A, const sp<Allocation>& B, const sp<Allocation>& C) {
168449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (!A->getType()->getElement()->isCompatible(e) ||
168549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !B->getType()->getElement()->isCompatible(e) ||
168649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !C->getType()->getElement()->isCompatible(e)) {
168749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
168849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
168949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
169049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    // A must be square; can potentially be relaxed similar to TRSM
169149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int adim = A->getType()->getX();
169249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (adim != (int)A->getType()->getY()) {
169349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called HEMM with non-square A");
169449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
169549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if ((Side == RsBlasLeft && adim != (int)B->getType()->getY()) ||
169649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        (Side == RsBlasRight && adim != (int)B->getType()->getX())) {
169749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called HEMM with invalid B");
169849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
169949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (B->getType()->getX() != C->getType()->getX() ||
170049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        B->getType()->getY() != C->getType()->getY()) {
170149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called HEMM with mismatched B and C");
170249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
170349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
170449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
170549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::CHEMM(RsBlasSide Side, RsBlasUplo Uplo, Float2 alpha,
170645768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, const sp<Allocation>& B, Float2 beta, const sp<Allocation>& C) {
170749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateHEMM(mRS, Element::F32_2(mRS), Side, A, B, C);
170849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_chemm,
170949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 0, 0, Side, Uplo, 0,
171049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 C->getType()->getY(), C->getType()->getX(), 0,
171149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha.x, alpha.y, A->getID(), B->getID(),
171249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 beta.x, beta.y, C->getID(), 0, 0, 0, 0);
171349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
171449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
171549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::ZHEMM(RsBlasSide Side, RsBlasUplo Uplo, Double2 alpha,
171645768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, const sp<Allocation>& B, Double2 beta, const sp<Allocation>& C) {
171749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateHEMM(mRS, Element::F64_2(mRS), Side, A, B, C);
171849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zhemm,
171949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           0, 0, Side, Uplo, 0,
172049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           C->getType()->getY(), C->getType()->getX(), 0,
172149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha.x, alpha.y, A->getID(), B->getID(),
172249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           beta.x, beta.y, C->getID(), 0, 0, 0, 0);
172349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
172449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
172545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic void validateHERK(RS* mRS, const sp<const Element>& e, RsBlasTranspose Trans,
172645768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                         const sp<Allocation>& A, const sp<Allocation>& C) {
172749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (!A->getType()->getElement()->isCompatible(e) ||
172849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !C->getType()->getElement()->isCompatible(e)) {
172949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
173049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
173149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Trans != RsBlasNoTrans && Trans != RsBlasConjTrans) {
173249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Call HERK with invalid Transpose");
173349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
173449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int cdim = C->getType()->getX();
173549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (cdim != (int)C->getType()->getY()) {
173649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called HERK with non-square C");
173749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
173849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Trans == RsBlasNoTrans) {
173949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        if (cdim != (int)A->getType()->getY()) {
174049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called HERK with invalid A");
174149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        }
174249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
174349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        if (cdim != (int)A->getType()->getX()) {
174449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called HERK with invalid A");
174549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        }
174649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
174749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
174849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
174949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::CHERK(RsBlasUplo Uplo, RsBlasTranspose Trans, float alpha,
175045768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, float beta, const sp<Allocation>& C) {
175149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateHERK(mRS, Element::F32_2(mRS), Trans, A, C);
175249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int k = 0;
175349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Trans == RsBlasConjTrans) {
175449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        k = A->getType()->getY();
175549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
175649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        k = A->getType()->getX();
175749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
175849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_cherk,
175949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 Trans, 0, 0, Uplo, 0, 0, C->getType()->getX(), k,
176049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha, 0, A->getID(), 0,
176149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 beta, 0, C->getID(), 0, 0, 0, 0);
176249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
176349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
176449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::ZHERK(RsBlasUplo Uplo, RsBlasTranspose Trans, double alpha,
176545768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                const sp<Allocation>& A, double beta, const sp<Allocation>& C) {
176649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateHERK(mRS, Element::F64_2(mRS), Trans, A, C);
176749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int k = 0;
176849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Trans == RsBlasConjTrans) {
176949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        k = A->getType()->getY();
177049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
177149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        k = A->getType()->getX();
177249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
177349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zherk,
177449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           Trans, 0, 0, Uplo, 0, 0, C->getType()->getX(), k,
177549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha, 0, A->getID(), 0,
177649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           beta, 0, C->getID(), 0, 0, 0, 0);
177749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
177849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
177945768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehstatic void validateHER2K(RS* mRS, const sp<const Element>& e, RsBlasTranspose Trans,
178045768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                          const sp<Allocation>& A, const sp<Allocation>& B, const sp<Allocation>& C) {
178149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (!A->getType()->getElement()->isCompatible(e) ||
178249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !B->getType()->getElement()->isCompatible(e) ||
178349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        !C->getType()->getElement()->isCompatible(e)) {
178449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_ELEMENT, "Called BLAS with wrong Element type");
178549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
178649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Trans != RsBlasNoTrans && Trans != RsBlasConjTrans) {
178749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Call HERK with invalid Transpose");
178849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
178949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int cdim = C->getType()->getX();
179049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (cdim != (int)C->getType()->getY()) {
179149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called HER2K with non-square C");
179249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
179349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Trans == RsBlasNoTrans) {
179449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        if ((int)A->getType()->getY() != cdim) {
179549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called HER2K with invalid matrices");
179649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        }
179749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
179849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        if ((int)A->getType()->getX() != cdim) {
179949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang            mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called HER2K with invalid matrices");
180049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        }
180149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
180249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (A->getType()->getX() != B->getType()->getX() || A->getType()->getY() != B->getType()->getY()) {
180349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Called HER2K with invalid A and B matrices");
180449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
180549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
180649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
180749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::CHER2K(RsBlasUplo Uplo, RsBlasTranspose Trans, Float2 alpha,
180845768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                 const sp<Allocation>& A, const sp<Allocation>& B, float beta, const sp<Allocation>& C) {
180949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateHER2K(mRS, Element::F32_2(mRS), Trans, A, B, C);
181049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int k = 0;
181149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Trans == RsBlasNoTrans) {
181249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        k = A->getType()->getX();
181349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
181449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        k = A->getType()->getY();
181549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
181649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Complex(mRS, mRS->getContext(), getID(), RsBlas_cher2k,
181749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 Trans, 0, 0, Uplo, 0, 0, C->getType()->getX(), k,
181849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 alpha.x, alpha.y, A->getID(), B->getID(),
181949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                                 beta, 0, C->getID(), 0, 0, 0, 0);
182049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
182149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
182249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wangvoid ScriptIntrinsicBLAS::ZHER2K(RsBlasUplo Uplo, RsBlasTranspose Trans, Double2 alpha,
182345768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                                 const sp<Allocation>& A, const sp<Allocation>& B, double beta, const sp<Allocation>& C) {
182449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateHER2K(mRS, Element::F64_2(mRS), Trans, A, B, C);
182549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int k = 0;
182649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (Trans == RsBlasNoTrans) {
182749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        k = A->getType()->getX();
182849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    } else {
182949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        k = A->getType()->getY();
183049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
183149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_Z(mRS, mRS->getContext(), getID(), RsBlas_zher2k,
183249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           Trans, 0, 0, Uplo, 0, 0, C->getType()->getX(), k,
183349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           alpha.x, alpha.y, A->getID(), B->getID(),
183449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                           beta, 0, C->getID(), 0, 0, 0, 0);
183549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
183649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
183749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
183849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
183945768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsiehvoid ScriptIntrinsicBLAS::BNNM(const sp<Allocation>& A, int a_offset, const sp<Allocation>& B, int b_offset,
184045768e1663714702c0c2b7adf14fdbd80dae71f5Chih-Hung Hsieh                               const sp<Allocation>& C, int c_offset, int c_mult) {
184149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    validateL3(mRS, Element::U8(mRS), RsBlasNoTrans, RsBlasTrans, 0, A, B, C);
184249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
184349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (a_offset < 0 || a_offset > 255) {
184449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid a_offset passed to BNNM");
184549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
184649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    if (b_offset < 0 || b_offset > 255) {
184749b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid b_offset passed to BNNM");
184849b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    }
184949b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    int M = -1, N = -1, K = -1;
185049b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    M = A->getType()->getY();
185149b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    N = B->getType()->getY();
185249b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    K = A->getType()->getX();
185349b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang
185449b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang    nScriptIntrinsicBLAS_BNNM(mRS, mRS->getContext(), getID(), M, N, K, A->getID(), a_offset,
185549b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang                              B->getID(), b_offset, C->getID(), c_offset, c_mult);
185649b1226e8399f2ad4a9fd4482ece95dab2ad53b8Miao Wang}
1857