Merge branch 'master' into xsn/mergekit_extract_lora_compat
This commit is contained in:
commit
65a431dbbc
11 changed files with 834 additions and 80 deletions
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
@ -665,7 +665,7 @@ jobs:
|
||||||
- build: 'llvm-arm64'
|
- build: 'llvm-arm64'
|
||||||
defines: '-G "Ninja Multi-Config" -D CMAKE_TOOLCHAIN_FILE=cmake/arm64-windows-llvm.cmake -DGGML_NATIVE=OFF -DLLAMA_BUILD_SERVER=ON'
|
defines: '-G "Ninja Multi-Config" -D CMAKE_TOOLCHAIN_FILE=cmake/arm64-windows-llvm.cmake -DGGML_NATIVE=OFF -DLLAMA_BUILD_SERVER=ON'
|
||||||
- build: 'msvc-arm64'
|
- build: 'msvc-arm64'
|
||||||
defines: '-G "Ninja Multi-Config" -D CMAKE_TOOLCHAIN_FILE=cmake/arm64-windows-msvc.cmake -DGGML_NATIVE=OFF -DLLAMA_BUILD_SERVER=ON -DBUILD_SHARED_LIBS=O'
|
defines: '-G "Ninja Multi-Config" -D CMAKE_TOOLCHAIN_FILE=cmake/arm64-windows-msvc.cmake -DGGML_NATIVE=OFF -DLLAMA_BUILD_SERVER=ON'
|
||||||
- build: 'llvm-arm64-opencl-adreno'
|
- build: 'llvm-arm64-opencl-adreno'
|
||||||
defines: '-G "Ninja Multi-Config" -D CMAKE_TOOLCHAIN_FILE=cmake/arm64-windows-llvm.cmake -DCMAKE_PREFIX_PATH="$env:RUNNER_TEMP/opencl-arm64-release" -DGGML_OPENCL=ON -DGGML_OPENCL_USE_ADRENO_KERNELS=ON'
|
defines: '-G "Ninja Multi-Config" -D CMAKE_TOOLCHAIN_FILE=cmake/arm64-windows-llvm.cmake -DCMAKE_PREFIX_PATH="$env:RUNNER_TEMP/opencl-arm64-release" -DGGML_OPENCL=ON -DGGML_OPENCL_USE_ADRENO_KERNELS=ON'
|
||||||
|
|
||||||
|
|
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
|
@ -100,7 +100,7 @@ jobs:
|
||||||
# https://github.com/jlumbroso/free-disk-space/tree/54081f138730dfa15788a46383842cd2f914a1be#example
|
# https://github.com/jlumbroso/free-disk-space/tree/54081f138730dfa15788a46383842cd2f914a1be#example
|
||||||
- name: Free Disk Space (Ubuntu)
|
- name: Free Disk Space (Ubuntu)
|
||||||
if: ${{ matrix.config.free_disk_space == true }}
|
if: ${{ matrix.config.free_disk_space == true }}
|
||||||
uses: jlumbroso/free-disk-space@main
|
uses: jlumbroso/free-disk-space@v1.3.1
|
||||||
with:
|
with:
|
||||||
# this might remove tools that are actually needed,
|
# this might remove tools that are actually needed,
|
||||||
# if set to "true" but frees about 6 GB
|
# if set to "true" but frees about 6 GB
|
||||||
|
|
4
.github/workflows/editorconfig.yml
vendored
4
.github/workflows/editorconfig.yml
vendored
|
@ -23,5 +23,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: editorconfig-checker/action-editorconfig-checker@main
|
- uses: editorconfig-checker/action-editorconfig-checker@v2
|
||||||
|
with:
|
||||||
|
version: v3.0.3
|
||||||
- run: editorconfig-checker
|
- run: editorconfig-checker
|
||||||
|
|
|
@ -22,6 +22,11 @@ common_arg & common_arg::set_examples(std::initializer_list<enum llama_example>
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
common_arg & common_arg::set_excludes(std::initializer_list<enum llama_example> excludes) {
|
||||||
|
this->excludes = std::move(excludes);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
common_arg & common_arg::set_env(const char * env) {
|
common_arg & common_arg::set_env(const char * env) {
|
||||||
help = help + "\n(env: " + env + ")";
|
help = help + "\n(env: " + env + ")";
|
||||||
this->env = env;
|
this->env = env;
|
||||||
|
@ -37,6 +42,10 @@ bool common_arg::in_example(enum llama_example ex) {
|
||||||
return examples.find(ex) != examples.end();
|
return examples.find(ex) != examples.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool common_arg::is_exclude(enum llama_example ex) {
|
||||||
|
return excludes.find(ex) != excludes.end();
|
||||||
|
}
|
||||||
|
|
||||||
bool common_arg::get_value_from_env(std::string & output) {
|
bool common_arg::get_value_from_env(std::string & output) {
|
||||||
if (env == nullptr) return false;
|
if (env == nullptr) return false;
|
||||||
char * value = std::getenv(env);
|
char * value = std::getenv(env);
|
||||||
|
@ -420,7 +429,7 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
|
||||||
* - if both {LLAMA_EXAMPLE_COMMON, LLAMA_EXAMPLE_*,} are set, we will prioritize the LLAMA_EXAMPLE_* matching current example
|
* - if both {LLAMA_EXAMPLE_COMMON, LLAMA_EXAMPLE_*,} are set, we will prioritize the LLAMA_EXAMPLE_* matching current example
|
||||||
*/
|
*/
|
||||||
auto add_opt = [&](common_arg arg) {
|
auto add_opt = [&](common_arg arg) {
|
||||||
if (arg.in_example(ex) || arg.in_example(LLAMA_EXAMPLE_COMMON)) {
|
if ((arg.in_example(ex) || arg.in_example(LLAMA_EXAMPLE_COMMON)) && !arg.is_exclude(ex)) {
|
||||||
ctx_arg.options.push_back(std::move(arg));
|
ctx_arg.options.push_back(std::move(arg));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -649,7 +658,7 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
|
||||||
[](common_params & params, const std::string & value) {
|
[](common_params & params, const std::string & value) {
|
||||||
params.prompt = value;
|
params.prompt = value;
|
||||||
}
|
}
|
||||||
));
|
).set_excludes({LLAMA_EXAMPLE_SERVER}));
|
||||||
add_opt(common_arg(
|
add_opt(common_arg(
|
||||||
{"--no-perf"},
|
{"--no-perf"},
|
||||||
string_format("disable internal libllama performance timings (default: %s)", params.no_perf ? "true" : "false"),
|
string_format("disable internal libllama performance timings (default: %s)", params.no_perf ? "true" : "false"),
|
||||||
|
@ -673,7 +682,7 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
|
||||||
params.prompt.pop_back();
|
params.prompt.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
));
|
).set_excludes({LLAMA_EXAMPLE_SERVER}));
|
||||||
add_opt(common_arg(
|
add_opt(common_arg(
|
||||||
{"--in-file"}, "FNAME",
|
{"--in-file"}, "FNAME",
|
||||||
"an input file (repeat to specify multiple files)",
|
"an input file (repeat to specify multiple files)",
|
||||||
|
@ -700,7 +709,7 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
|
||||||
params.prompt = ss.str();
|
params.prompt = ss.str();
|
||||||
fprintf(stderr, "Read %zu bytes from binary file %s\n", params.prompt.size(), value.c_str());
|
fprintf(stderr, "Read %zu bytes from binary file %s\n", params.prompt.size(), value.c_str());
|
||||||
}
|
}
|
||||||
));
|
).set_excludes({LLAMA_EXAMPLE_SERVER}));
|
||||||
add_opt(common_arg(
|
add_opt(common_arg(
|
||||||
{"-e", "--escape"},
|
{"-e", "--escape"},
|
||||||
string_format("process escapes sequences (\\n, \\r, \\t, \\', \\\", \\\\) (default: %s)", params.escape ? "true" : "false"),
|
string_format("process escapes sequences (\\n, \\r, \\t, \\', \\\", \\\\) (default: %s)", params.escape ? "true" : "false"),
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
struct common_arg {
|
struct common_arg {
|
||||||
std::set<enum llama_example> examples = {LLAMA_EXAMPLE_COMMON};
|
std::set<enum llama_example> examples = {LLAMA_EXAMPLE_COMMON};
|
||||||
|
std::set<enum llama_example> excludes = {};
|
||||||
std::vector<const char *> args;
|
std::vector<const char *> args;
|
||||||
const char * value_hint = nullptr; // help text or example for arg value
|
const char * value_hint = nullptr; // help text or example for arg value
|
||||||
const char * value_hint_2 = nullptr; // for second arg value
|
const char * value_hint_2 = nullptr; // for second arg value
|
||||||
|
@ -53,9 +54,11 @@ struct common_arg {
|
||||||
) : args(args), value_hint(value_hint), value_hint_2(value_hint_2), help(help), handler_str_str(handler) {}
|
) : args(args), value_hint(value_hint), value_hint_2(value_hint_2), help(help), handler_str_str(handler) {}
|
||||||
|
|
||||||
common_arg & set_examples(std::initializer_list<enum llama_example> examples);
|
common_arg & set_examples(std::initializer_list<enum llama_example> examples);
|
||||||
|
common_arg & set_excludes(std::initializer_list<enum llama_example> excludes);
|
||||||
common_arg & set_env(const char * env);
|
common_arg & set_env(const char * env);
|
||||||
common_arg & set_sparam();
|
common_arg & set_sparam();
|
||||||
bool in_example(enum llama_example ex);
|
bool in_example(enum llama_example ex);
|
||||||
|
bool is_exclude(enum llama_example ex);
|
||||||
bool get_value_from_env(std::string & output);
|
bool get_value_from_env(std::string & output);
|
||||||
bool has_value_from_env();
|
bool has_value_from_env();
|
||||||
std::string to_string();
|
std::string to_string();
|
||||||
|
|
|
@ -45,10 +45,7 @@ The project is under active development, and we are [looking for feedback and co
|
||||||
| `-ub, --ubatch-size N` | physical maximum batch size (default: 512)<br/>(env: LLAMA_ARG_UBATCH) |
|
| `-ub, --ubatch-size N` | physical maximum batch size (default: 512)<br/>(env: LLAMA_ARG_UBATCH) |
|
||||||
| `--keep N` | number of tokens to keep from the initial prompt (default: 0, -1 = all) |
|
| `--keep N` | number of tokens to keep from the initial prompt (default: 0, -1 = all) |
|
||||||
| `-fa, --flash-attn` | enable Flash Attention (default: disabled)<br/>(env: LLAMA_ARG_FLASH_ATTN) |
|
| `-fa, --flash-attn` | enable Flash Attention (default: disabled)<br/>(env: LLAMA_ARG_FLASH_ATTN) |
|
||||||
| `-p, --prompt PROMPT` | prompt to start generation with |
|
|
||||||
| `--no-perf` | disable internal libllama performance timings (default: false)<br/>(env: LLAMA_ARG_NO_PERF) |
|
| `--no-perf` | disable internal libllama performance timings (default: false)<br/>(env: LLAMA_ARG_NO_PERF) |
|
||||||
| `-f, --file FNAME` | a file containing the prompt (default: none) |
|
|
||||||
| `-bf, --binary-file FNAME` | binary file containing the prompt (default: none) |
|
|
||||||
| `-e, --escape` | process escapes sequences (\n, \r, \t, \', \", \\) (default: true) |
|
| `-e, --escape` | process escapes sequences (\n, \r, \t, \', \", \\) (default: true) |
|
||||||
| `--no-escape` | do not process escape sequences |
|
| `--no-escape` | do not process escape sequences |
|
||||||
| `--rope-scaling {none,linear,yarn}` | RoPE frequency scaling method, defaults to linear unless specified by the model<br/>(env: LLAMA_ARG_ROPE_SCALING_TYPE) |
|
| `--rope-scaling {none,linear,yarn}` | RoPE frequency scaling method, defaults to linear unless specified by the model<br/>(env: LLAMA_ARG_ROPE_SCALING_TYPE) |
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#include "ggml-quants.h"
|
#include "ggml-quants.h"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define NOINLINE __declspec(noinline)
|
#define NOINLINE __declspec(noinline)
|
||||||
|
@ -1051,6 +1052,704 @@ class tinyBLAS_Q0_AVX {
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
|
template <typename TA, typename TB, typename TC>
|
||||||
|
class tinyBLAS_Q0_PPC {
|
||||||
|
public:
|
||||||
|
tinyBLAS_Q0_PPC(int64_t k,
|
||||||
|
const TA *A, int64_t lda,
|
||||||
|
const TB *B, int64_t ldb,
|
||||||
|
TC *C, int64_t ldc,
|
||||||
|
int ith, int nth)
|
||||||
|
: A(A), B(B), C(C), k(k), lda(lda), ldb(ldb), ldc(ldc), ith(ith), nth(nth) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void matmul(int64_t m, int64_t n) {
|
||||||
|
mnpack(0, m, 0, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
template<int RM, int RN>
|
||||||
|
inline void save_res(int ii, int jj, int idx, vector float* fin_res) {
|
||||||
|
for (int I = 0; I < RM; I++) {
|
||||||
|
for (int J = 0; J < RN; J++) {
|
||||||
|
*((float*)(C+ii+((jj+J)*ldc)+I)) = *((float*)&fin_res[idx+I]+J);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int size>
|
||||||
|
inline void compute(acc_t* ACC, int c_idx, int s_idx, std::array<int, size>& comparray, vector float* vs, vector float* fin_res) {
|
||||||
|
vector signed int vec_C[4];
|
||||||
|
vector float CA[4] = {0};
|
||||||
|
vector float res[4] = {0};
|
||||||
|
__builtin_mma_disassemble_acc(vec_C, ACC);
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
CA[i] = vec_splats((float)(((double)comparray[c_idx+i]) * -128.0));
|
||||||
|
res[i] = vec_add(vec_ctf(vec_C[i], 0), CA[i]);
|
||||||
|
fin_res[s_idx+i] = vec_madd(res[i], vs[s_idx+i], fin_res[s_idx+i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename VA, typename VB>
|
||||||
|
void packNormal(const TA* a, int64_t lda, int rows, int cols, VA* vec, bool flip) {
|
||||||
|
int64_t i, j;
|
||||||
|
TA *aoffset = NULL;
|
||||||
|
VA *vecOffset = NULL;
|
||||||
|
TA *aoffset1 = NULL, *aoffset2 = NULL, *aoffset3 = NULL, *aoffset4 = NULL;
|
||||||
|
TA *aoffset5 = NULL, *aoffset6 = NULL, *aoffset7 = NULL, *aoffset8 = NULL;
|
||||||
|
__vector_pair C1, C2, C3, C4, C5, C6, C7, C8;
|
||||||
|
VB c1[2] = {0}, c2[2] = {0}, c3[2] = {0}, c4[2]={0};
|
||||||
|
VB c5[2] = {0}, c6[2] = {0}, c7[2] = {0}, c8[2]={0};
|
||||||
|
VB t1, t2, t3, t4, t5, t6, t7, t8;
|
||||||
|
vector unsigned char xor_vector;
|
||||||
|
uint8_t flip_vec = 0x80;
|
||||||
|
xor_vector = vec_splats(flip_vec);
|
||||||
|
vector unsigned char swiz1 = {0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23};
|
||||||
|
vector unsigned char swiz2 = {8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31};
|
||||||
|
vector unsigned char swiz3 = {0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27};
|
||||||
|
vector unsigned char swiz4 = {4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31};
|
||||||
|
|
||||||
|
aoffset = const_cast<TA*>(a);
|
||||||
|
vecOffset = vec;
|
||||||
|
j = (rows >> 3);
|
||||||
|
if (j > 0) {
|
||||||
|
do {
|
||||||
|
aoffset1 = aoffset;
|
||||||
|
aoffset2 = aoffset1 + lda;
|
||||||
|
aoffset3 = aoffset2 + lda;
|
||||||
|
aoffset4 = aoffset3 + lda;
|
||||||
|
aoffset5 = aoffset4 + lda;
|
||||||
|
aoffset6 = aoffset5 + lda;
|
||||||
|
aoffset7 = aoffset6 + lda;
|
||||||
|
aoffset8 = aoffset7 + lda;
|
||||||
|
aoffset += 8 * lda;
|
||||||
|
|
||||||
|
i = (cols >> 3);
|
||||||
|
if (i > 0) {
|
||||||
|
do {
|
||||||
|
C1 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset1->qs);
|
||||||
|
C2 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset2->qs);
|
||||||
|
C3 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset3->qs);
|
||||||
|
C4 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset4->qs);
|
||||||
|
C5 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset5->qs);
|
||||||
|
C6 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset6->qs);
|
||||||
|
C7 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset7->qs);
|
||||||
|
C8 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset8->qs);
|
||||||
|
|
||||||
|
__builtin_vsx_disassemble_pair(c1, &C1);
|
||||||
|
__builtin_vsx_disassemble_pair(c2, &C2);
|
||||||
|
__builtin_vsx_disassemble_pair(c3, &C3);
|
||||||
|
__builtin_vsx_disassemble_pair(c4, &C4);
|
||||||
|
__builtin_vsx_disassemble_pair(c5, &C5);
|
||||||
|
__builtin_vsx_disassemble_pair(c6, &C6);
|
||||||
|
__builtin_vsx_disassemble_pair(c7, &C7);
|
||||||
|
__builtin_vsx_disassemble_pair(c8, &C8);
|
||||||
|
|
||||||
|
t1 = vec_perm(c1[0], c2[0], swiz1);
|
||||||
|
t2 = vec_perm(c1[0], c2[0], swiz2);
|
||||||
|
t3 = vec_perm(c3[0], c4[0], swiz1);
|
||||||
|
t4 = vec_perm(c3[0], c4[0], swiz2);
|
||||||
|
t5 = vec_perm(t1, t3, swiz3);
|
||||||
|
t6 = vec_perm(t1, t3, swiz4);
|
||||||
|
t7 = vec_perm(t2, t4, swiz3);
|
||||||
|
t8 = vec_perm(t2, t4, swiz4);
|
||||||
|
if (flip == true) {
|
||||||
|
t5 = vec_xor(t5, xor_vector);
|
||||||
|
t6 = vec_xor(t6, xor_vector);
|
||||||
|
t7 = vec_xor(t7, xor_vector);
|
||||||
|
t8 = vec_xor(t8, xor_vector);
|
||||||
|
}
|
||||||
|
vec_xst(t5, 0, vecOffset);
|
||||||
|
vec_xst(t6, 0, vecOffset+16);
|
||||||
|
vec_xst(t7, 0, vecOffset+32);
|
||||||
|
vec_xst(t8, 0, vecOffset+48);
|
||||||
|
|
||||||
|
t1 = vec_perm(c1[1], c2[1], swiz1);
|
||||||
|
t2 = vec_perm(c1[1], c2[1], swiz2);
|
||||||
|
t3 = vec_perm(c3[1], c4[1], swiz1);
|
||||||
|
t4 = vec_perm(c3[1], c4[1], swiz2);
|
||||||
|
t5 = vec_perm(t1, t3, swiz3);
|
||||||
|
t6 = vec_perm(t1, t3, swiz4);
|
||||||
|
t7 = vec_perm(t2, t4, swiz3);
|
||||||
|
t8 = vec_perm(t2, t4, swiz4);
|
||||||
|
if (flip == true) {
|
||||||
|
t5 = vec_xor(t5, xor_vector);
|
||||||
|
t6 = vec_xor(t6, xor_vector);
|
||||||
|
t7 = vec_xor(t7, xor_vector);
|
||||||
|
t8 = vec_xor(t8, xor_vector);
|
||||||
|
}
|
||||||
|
vec_xst(t5, 0, vecOffset+64);
|
||||||
|
vec_xst(t6, 0, vecOffset+80);
|
||||||
|
vec_xst(t7, 0, vecOffset+96);
|
||||||
|
vec_xst(t8, 0, vecOffset+112);
|
||||||
|
|
||||||
|
t1 = vec_perm(c5[0], c6[0], swiz1);
|
||||||
|
t2 = vec_perm(c5[0], c6[0], swiz2);
|
||||||
|
t3 = vec_perm(c7[0], c8[0], swiz1);
|
||||||
|
t4 = vec_perm(c7[0], c8[0], swiz2);
|
||||||
|
t5 = vec_perm(t1, t3, swiz3);
|
||||||
|
t6 = vec_perm(t1, t3, swiz4);
|
||||||
|
t7 = vec_perm(t2, t4, swiz3);
|
||||||
|
t8 = vec_perm(t2, t4, swiz4);
|
||||||
|
if (flip == true) {
|
||||||
|
t5 = vec_xor(t5, xor_vector);
|
||||||
|
t6 = vec_xor(t6, xor_vector);
|
||||||
|
t7 = vec_xor(t7, xor_vector);
|
||||||
|
t8 = vec_xor(t8, xor_vector);
|
||||||
|
}
|
||||||
|
vec_xst(t5, 0, vecOffset+128);
|
||||||
|
vec_xst(t6, 0, vecOffset+144);
|
||||||
|
vec_xst(t7, 0, vecOffset+160);
|
||||||
|
vec_xst(t8, 0, vecOffset+176);
|
||||||
|
|
||||||
|
t1 = vec_perm(c5[1], c6[1], swiz1);
|
||||||
|
t2 = vec_perm(c5[1], c6[1], swiz2);
|
||||||
|
t3 = vec_perm(c7[1], c8[1], swiz1);
|
||||||
|
t4 = vec_perm(c7[1], c8[1], swiz2);
|
||||||
|
t5 = vec_perm(t1, t3, swiz3);
|
||||||
|
t6 = vec_perm(t1, t3, swiz4);
|
||||||
|
t7 = vec_perm(t2, t4, swiz3);
|
||||||
|
t8 = vec_perm(t2, t4, swiz4);
|
||||||
|
if (flip == true) {
|
||||||
|
t5 = vec_xor(t5, xor_vector);
|
||||||
|
t6 = vec_xor(t6, xor_vector);
|
||||||
|
t7 = vec_xor(t7, xor_vector);
|
||||||
|
t8 = vec_xor(t8, xor_vector);
|
||||||
|
}
|
||||||
|
vec_xst(t5, 0, vecOffset+192);
|
||||||
|
vec_xst(t6, 0, vecOffset+208);
|
||||||
|
vec_xst(t7, 0, vecOffset+224);
|
||||||
|
vec_xst(t8, 0, vecOffset+240);
|
||||||
|
|
||||||
|
aoffset1 += lda;
|
||||||
|
aoffset2 += lda;
|
||||||
|
aoffset3 += lda;
|
||||||
|
aoffset4 += lda;
|
||||||
|
aoffset5 += lda;
|
||||||
|
aoffset6 += lda;
|
||||||
|
aoffset7 += lda;
|
||||||
|
aoffset8 += lda;
|
||||||
|
vecOffset += 256;
|
||||||
|
i--;
|
||||||
|
} while(i > 0);
|
||||||
|
}
|
||||||
|
j--;
|
||||||
|
} while(j > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rows & 4) {
|
||||||
|
aoffset1 = aoffset;
|
||||||
|
aoffset2 = aoffset1 + lda;
|
||||||
|
aoffset3 = aoffset2 + lda;
|
||||||
|
aoffset4 = aoffset3 + lda;
|
||||||
|
aoffset += 4 * lda;
|
||||||
|
|
||||||
|
i = (cols >> 3);
|
||||||
|
if (i > 0) {
|
||||||
|
do {
|
||||||
|
C1 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset1->qs);
|
||||||
|
C2 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset2->qs);
|
||||||
|
C3 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset3->qs);
|
||||||
|
C4 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset4->qs);
|
||||||
|
|
||||||
|
__builtin_vsx_disassemble_pair(c1, &C1);
|
||||||
|
__builtin_vsx_disassemble_pair(c2, &C2);
|
||||||
|
__builtin_vsx_disassemble_pair(c3, &C3);
|
||||||
|
__builtin_vsx_disassemble_pair(c4, &C4);
|
||||||
|
|
||||||
|
t1 = vec_perm(c1[0], c2[0], swiz1);
|
||||||
|
t2 = vec_perm(c1[0], c2[0], swiz2);
|
||||||
|
t3 = vec_perm(c3[0], c4[0], swiz1);
|
||||||
|
t4 = vec_perm(c3[0], c4[0], swiz2);
|
||||||
|
t5 = vec_perm(t1, t3, swiz3);
|
||||||
|
t6 = vec_perm(t1, t3, swiz4);
|
||||||
|
t7 = vec_perm(t2, t4, swiz3);
|
||||||
|
t8 = vec_perm(t2, t4, swiz4);
|
||||||
|
if (flip == true) {
|
||||||
|
t5 = vec_xor(t5, xor_vector);
|
||||||
|
t6 = vec_xor(t6, xor_vector);
|
||||||
|
t7 = vec_xor(t7, xor_vector);
|
||||||
|
t8 = vec_xor(t8, xor_vector);
|
||||||
|
}
|
||||||
|
vec_xst(t5, 0, vecOffset);
|
||||||
|
vec_xst(t6, 0, vecOffset+16);
|
||||||
|
vec_xst(t7, 0, vecOffset+32);
|
||||||
|
vec_xst(t8, 0, vecOffset+48);
|
||||||
|
|
||||||
|
t1 = vec_perm(c1[1], c2[1], swiz1);
|
||||||
|
t2 = vec_perm(c1[1], c2[1], swiz2);
|
||||||
|
t3 = vec_perm(c3[1], c4[1], swiz1);
|
||||||
|
t4 = vec_perm(c3[1], c4[1], swiz2);
|
||||||
|
t5 = vec_perm(t1, t3, swiz3);
|
||||||
|
t6 = vec_perm(t1, t3, swiz4);
|
||||||
|
t7 = vec_perm(t2, t4, swiz3);
|
||||||
|
t8 = vec_perm(t2, t4, swiz4);
|
||||||
|
if (flip == true) {
|
||||||
|
t5 = vec_xor(t5, xor_vector);
|
||||||
|
t6 = vec_xor(t6, xor_vector);
|
||||||
|
t7 = vec_xor(t7, xor_vector);
|
||||||
|
t8 = vec_xor(t8, xor_vector);
|
||||||
|
}
|
||||||
|
vec_xst(t5, 0, vecOffset+64);
|
||||||
|
vec_xst(t6, 0, vecOffset+80);
|
||||||
|
vec_xst(t7, 0, vecOffset+96);
|
||||||
|
vec_xst(t8, 0, vecOffset+112);
|
||||||
|
|
||||||
|
aoffset1 += lda;
|
||||||
|
aoffset2 += lda;
|
||||||
|
aoffset3 += lda;
|
||||||
|
aoffset4 += lda;
|
||||||
|
vecOffset += 128;
|
||||||
|
i--;
|
||||||
|
} while(i > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rows & 3) {
|
||||||
|
aoffset1 = aoffset;
|
||||||
|
aoffset2 = aoffset1 + lda;
|
||||||
|
aoffset3 = aoffset2 + lda;
|
||||||
|
i = (cols >> 3);
|
||||||
|
if (i > 0) {
|
||||||
|
do {
|
||||||
|
switch(rows) {
|
||||||
|
case 3: C3 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset3->qs);
|
||||||
|
__builtin_vsx_disassemble_pair(c3, &C3);
|
||||||
|
case 2: C2 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset2->qs);
|
||||||
|
__builtin_vsx_disassemble_pair(c2, &C2);
|
||||||
|
case 1: C1 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset1->qs);
|
||||||
|
__builtin_vsx_disassemble_pair(c1, &C1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
t1 = vec_perm(c1[0], c2[0], swiz1);
|
||||||
|
t2 = vec_perm(c1[0], c2[0], swiz2);
|
||||||
|
t3 = vec_perm(c3[0], c4[0], swiz1);
|
||||||
|
t4 = vec_perm(c3[0], c4[0], swiz2);
|
||||||
|
t5 = vec_perm(t1, t3, swiz3);
|
||||||
|
t6 = vec_perm(t1, t3, swiz4);
|
||||||
|
t7 = vec_perm(t2, t4, swiz3);
|
||||||
|
t8 = vec_perm(t2, t4, swiz4);
|
||||||
|
if (flip == true) {
|
||||||
|
t5 = vec_xor(t5, xor_vector);
|
||||||
|
t6 = vec_xor(t6, xor_vector);
|
||||||
|
t7 = vec_xor(t7, xor_vector);
|
||||||
|
t8 = vec_xor(t8, xor_vector);
|
||||||
|
}
|
||||||
|
vec_xst(t5, 0, vecOffset);
|
||||||
|
vec_xst(t6, 0, vecOffset+16);
|
||||||
|
vec_xst(t7, 0, vecOffset+32);
|
||||||
|
vec_xst(t8, 0, vecOffset+48);
|
||||||
|
|
||||||
|
t1 = vec_perm(c1[1], c2[1], swiz1);
|
||||||
|
t2 = vec_perm(c1[1], c2[1], swiz2);
|
||||||
|
t3 = vec_perm(c3[1], c4[1], swiz1);
|
||||||
|
t4 = vec_perm(c3[1], c4[1], swiz2);
|
||||||
|
t5 = vec_perm(t1, t3, swiz3);
|
||||||
|
t6 = vec_perm(t1, t3, swiz4);
|
||||||
|
t7 = vec_perm(t2, t4, swiz3);
|
||||||
|
t8 = vec_perm(t2, t4, swiz4);
|
||||||
|
if (flip == true) {
|
||||||
|
t5 = vec_xor(t5, xor_vector);
|
||||||
|
t6 = vec_xor(t6, xor_vector);
|
||||||
|
t7 = vec_xor(t7, xor_vector);
|
||||||
|
t8 = vec_xor(t8, xor_vector);
|
||||||
|
}
|
||||||
|
vec_xst(t5, 0, vecOffset+64);
|
||||||
|
vec_xst(t6, 0, vecOffset+80);
|
||||||
|
vec_xst(t7, 0, vecOffset+96);
|
||||||
|
vec_xst(t8, 0, vecOffset+112);
|
||||||
|
|
||||||
|
aoffset1 += lda;
|
||||||
|
aoffset2 += lda;
|
||||||
|
aoffset3 += lda;
|
||||||
|
vecOffset += 128;
|
||||||
|
i--;
|
||||||
|
} while(i > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mnpack(int64_t m0, int64_t m, int64_t n0, int64_t n) {
|
||||||
|
int64_t mc, nc, mp, np;
|
||||||
|
int m_rem = MIN(m - m0, 8);
|
||||||
|
int n_rem = MIN(n - n0, 8);
|
||||||
|
// TO-DO: KERNEL_16x8 and KERNEL_8x16 are having some performance
|
||||||
|
// issues. After resolving them, below code will be enabled.
|
||||||
|
/*if (m_rem >= 16 && n_rem >= 8) {
|
||||||
|
mc = 16;
|
||||||
|
nc = 8;
|
||||||
|
gemm<16,8>(m0, m, n0, n);
|
||||||
|
} else if(m_rem >= 8 && n_rem >= 16) {
|
||||||
|
mc = 8;
|
||||||
|
nc = 16;
|
||||||
|
gemm<8,16>(m0, m, n0, n);
|
||||||
|
}*/
|
||||||
|
if (m_rem >= 8 && n_rem >= 8) {
|
||||||
|
mc = 8;
|
||||||
|
nc = 8;
|
||||||
|
gemm<8,8>(m0, m, n0, n);
|
||||||
|
} else if (m_rem >= 4 && n_rem >= 8) {
|
||||||
|
mc = 4;
|
||||||
|
nc = 8;
|
||||||
|
gemm<4,8>(m0, m, n0, n);
|
||||||
|
} else if (m_rem >= 8 && n_rem >= 4) {
|
||||||
|
mc = 8;
|
||||||
|
nc = 4;
|
||||||
|
gemm<8,4>(m0, m, n0, n);
|
||||||
|
} else if (m_rem >= 4 && n_rem >= 4) {
|
||||||
|
mc = 4;
|
||||||
|
nc = 4;
|
||||||
|
gemm_small<4, 4>(m0, m, n0, n);
|
||||||
|
} else if ((m_rem < 4) && (n_rem > 4)) {
|
||||||
|
nc = 4;
|
||||||
|
switch(m_rem) {
|
||||||
|
case 1:
|
||||||
|
mc = 1;
|
||||||
|
gemm_small<1, 4>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
mc = 2;
|
||||||
|
gemm_small<2, 4>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
mc = 3;
|
||||||
|
gemm_small<3, 4>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if ((m_rem > 4) && (n_rem < 4)) {
|
||||||
|
mc = 4;
|
||||||
|
switch(n_rem) {
|
||||||
|
case 1:
|
||||||
|
nc = 1;
|
||||||
|
gemm_small<4, 1>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
nc = 2;
|
||||||
|
gemm_small<4, 2>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
nc = 3;
|
||||||
|
gemm_small<4, 3>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch((m_rem << 4) | n_rem) {
|
||||||
|
case 0x43:
|
||||||
|
mc = 4;
|
||||||
|
nc = 3;
|
||||||
|
gemm_small<4, 3>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 0x42:
|
||||||
|
mc = 4;
|
||||||
|
nc = 2;
|
||||||
|
gemm_small<4, 2>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 0x41:
|
||||||
|
mc = 4;
|
||||||
|
nc = 1;
|
||||||
|
gemm_small<4, 1>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 0x34:
|
||||||
|
mc = 3;
|
||||||
|
nc = 4;
|
||||||
|
gemm_small<3, 4>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 0x33:
|
||||||
|
mc = 3;
|
||||||
|
nc = 3;
|
||||||
|
gemm_small<3, 3>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 0x32:
|
||||||
|
mc = 3;
|
||||||
|
nc = 2;
|
||||||
|
gemm_small<3, 2>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 0x31:
|
||||||
|
mc = 3;
|
||||||
|
nc = 1;
|
||||||
|
gemm_small<3, 1>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 0x24:
|
||||||
|
mc = 2;
|
||||||
|
nc = 4;
|
||||||
|
gemm_small<2, 4>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 0x23:
|
||||||
|
mc = 2;
|
||||||
|
nc = 3;
|
||||||
|
gemm_small<2, 3>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 0x22:
|
||||||
|
mc = 2;
|
||||||
|
nc = 2;
|
||||||
|
gemm_small<2, 2>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 0x21:
|
||||||
|
mc = 2;
|
||||||
|
nc = 1;
|
||||||
|
gemm_small<2, 1>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 0x14:
|
||||||
|
mc = 1;
|
||||||
|
nc = 4;
|
||||||
|
gemm_small<1, 4>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 0x13:
|
||||||
|
mc = 1;
|
||||||
|
nc = 3;
|
||||||
|
gemm_small<1, 3>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 0x12:
|
||||||
|
mc = 1;
|
||||||
|
nc = 2;
|
||||||
|
gemm_small<1, 2>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
case 0x11:
|
||||||
|
mc = 1;
|
||||||
|
nc = 1;
|
||||||
|
gemm_small<1, 1>(m0, m, n0, n);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mp = m0 + (m - m0) / mc * mc;
|
||||||
|
np = n0 + (n - n0) / nc * nc;
|
||||||
|
mnpack(mp, m, n0, np);
|
||||||
|
mnpack(m0, m, np, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KERNEL_4x8(int64_t ii, int64_t jj) {
|
||||||
|
vec_t vec_A[8], vec_B[16] = {0};
|
||||||
|
acc_t acc_0, acc_1;
|
||||||
|
std::array<int, 4> comparray;
|
||||||
|
vector float fin_res[8] = {0};
|
||||||
|
vector float vs[8] = {0};
|
||||||
|
for (int l = 0; l < k; l++) {
|
||||||
|
__builtin_mma_xxsetaccz(&acc_0);
|
||||||
|
__builtin_mma_xxsetaccz(&acc_1);
|
||||||
|
packNormal<int8_t, vector signed char>((A+(ii*lda)+l), lda, 4, 8, (int8_t*)vec_A, false);
|
||||||
|
packNormal<uint8_t, vector unsigned char>((B+(jj*ldb)+l), ldb, 8, 8, (uint8_t*)vec_B, true);
|
||||||
|
for(int x = 0; x < 8; x++) {
|
||||||
|
__builtin_mma_xvi8ger4pp(&acc_0, vec_A[x], vec_B[x]);
|
||||||
|
__builtin_mma_xvi8ger4pp(&acc_1, vec_A[x], vec_B[x+8]);
|
||||||
|
}
|
||||||
|
for (int I = 0; I<4; I++) {
|
||||||
|
for (int J = 0; J<4; J++) {
|
||||||
|
*((float*)&vs[I]+J) = (unhalf((A+((ii+I)*lda)+l)->d) * unhalf((B+((jj+J)*ldb)+l)->d));
|
||||||
|
*((float*)&vs[I+4]+J) = (unhalf((A+((ii+I)*lda)+l)->d) * unhalf((B+((jj+J+4)*ldb)+l)->d));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto aoffset = A+(ii*lda)+l;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
comparray[i] = 0;
|
||||||
|
int ca = 0;
|
||||||
|
const int8_t *at = aoffset->qs;
|
||||||
|
for (int j = 0; j < 32; j++)
|
||||||
|
ca += (int)*at++;
|
||||||
|
comparray[i] = ca;
|
||||||
|
aoffset += lda;
|
||||||
|
}
|
||||||
|
compute<4>(&acc_0, 0, 0, comparray, vs, fin_res);
|
||||||
|
compute<4>(&acc_1, 0, 4, comparray, vs, fin_res);
|
||||||
|
}
|
||||||
|
save_res<4, 4>(ii, jj, 0, fin_res);
|
||||||
|
save_res<4, 4>(ii, jj+4, 4, fin_res);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KERNEL_8x4(int64_t ii, int64_t jj) {
|
||||||
|
vec_t vec_A[16], vec_B[8] = {0};
|
||||||
|
acc_t acc_0, acc_1;
|
||||||
|
std::array<int, 8> comparray;
|
||||||
|
vector float fin_res[8] = {0};
|
||||||
|
vector float vs[8] = {0};
|
||||||
|
for (int l = 0; l < k; l++) {
|
||||||
|
__builtin_mma_xxsetaccz(&acc_0);
|
||||||
|
__builtin_mma_xxsetaccz(&acc_1);
|
||||||
|
packNormal<int8_t, vector signed char>((A+(ii*lda)+l), lda, 8, 8, (int8_t*)vec_A, false);
|
||||||
|
packNormal<uint8_t, vector unsigned char>((B+(jj*ldb)+l), ldb, 4, 8, (uint8_t*)vec_B, true);
|
||||||
|
for(int x = 0; x < 8; x++) {
|
||||||
|
__builtin_mma_xvi8ger4pp(&acc_0, vec_A[x], vec_B[x]);
|
||||||
|
__builtin_mma_xvi8ger4pp(&acc_1, vec_A[x+8], vec_B[x]);
|
||||||
|
}
|
||||||
|
for (int I = 0; I<8; I++) {
|
||||||
|
for (int J = 0; J<4; J++) {
|
||||||
|
*((float*)&vs[I]+J) = (unhalf((A+((ii+I)*lda)+l)->d) * unhalf((B+((jj+J)*ldb)+l)->d));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto aoffset = A+(ii*lda)+l;
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
comparray[i] = 0;
|
||||||
|
int ca = 0;
|
||||||
|
const int8_t *at = aoffset->qs;
|
||||||
|
for (int j = 0; j < 32; j++)
|
||||||
|
ca += (int)*at++;
|
||||||
|
comparray[i] = ca;
|
||||||
|
aoffset += lda;
|
||||||
|
}
|
||||||
|
compute<8>(&acc_0, 0, 0, comparray, vs, fin_res);
|
||||||
|
compute<8>(&acc_1, 4, 4, comparray, vs, fin_res);
|
||||||
|
}
|
||||||
|
save_res<4, 4>(ii, jj, 0, fin_res);
|
||||||
|
save_res<4, 4>(ii+4, jj, 4, fin_res);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KERNEL_8x8(int64_t ii, int64_t jj) {
|
||||||
|
vec_t vec_A[16], vec_B[16] = {0};
|
||||||
|
acc_t acc_0, acc_1, acc_2, acc_3;
|
||||||
|
std::array<int, 8> comparray;
|
||||||
|
vector float fin_res[16] = {0};
|
||||||
|
vector float vs[16] = {0};
|
||||||
|
for (int l = 0; l < k; l++) {
|
||||||
|
__builtin_mma_xxsetaccz(&acc_0);
|
||||||
|
__builtin_mma_xxsetaccz(&acc_1);
|
||||||
|
__builtin_mma_xxsetaccz(&acc_2);
|
||||||
|
__builtin_mma_xxsetaccz(&acc_3);
|
||||||
|
packNormal<int8_t, vector signed char>((A+(ii*lda)+l), lda, 8, 8, (int8_t*)vec_A, false);
|
||||||
|
packNormal<uint8_t, vector unsigned char>((B+(jj*ldb)+l), ldb, 8, 8, (uint8_t*)vec_B, true);
|
||||||
|
for(int x = 0; x < 8; x++) {
|
||||||
|
__builtin_mma_xvi8ger4pp(&acc_0, vec_A[x], vec_B[x]);
|
||||||
|
__builtin_mma_xvi8ger4pp(&acc_1, vec_A[x+8], vec_B[x]);
|
||||||
|
__builtin_mma_xvi8ger4pp(&acc_2, vec_A[x], vec_B[x+8]);
|
||||||
|
__builtin_mma_xvi8ger4pp(&acc_3, vec_A[x+8], vec_B[x+8]);
|
||||||
|
}
|
||||||
|
for (int I = 0; I<8; I++) {
|
||||||
|
for (int J = 0; J<4; J++) {
|
||||||
|
*((float*)&vs[I]+J) = (unhalf((A+((ii+I)*lda)+l)->d) * unhalf((B+((jj+J)*ldb)+l)->d));
|
||||||
|
*((float*)&vs[I+8]+J) = (unhalf((A+((ii+I)*lda)+l)->d) * unhalf((B+((jj+J+4)*ldb)+l)->d));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto aoffset = A+(ii*lda)+l;
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
comparray[i] = 0;
|
||||||
|
int ca = 0;
|
||||||
|
const int8_t *at = aoffset->qs;
|
||||||
|
for (int j = 0; j < 32; j++)
|
||||||
|
ca += (int)*at++;
|
||||||
|
comparray[i] = ca;
|
||||||
|
aoffset += lda;
|
||||||
|
}
|
||||||
|
compute<8>(&acc_0, 0, 0, comparray, vs, fin_res);
|
||||||
|
compute<8>(&acc_1, 4, 4, comparray, vs, fin_res);
|
||||||
|
compute<8>(&acc_2, 0, 8, comparray, vs, fin_res);
|
||||||
|
compute<8>(&acc_3, 4, 12, comparray, vs, fin_res);
|
||||||
|
}
|
||||||
|
save_res<4, 4>(ii, jj, 0, fin_res);
|
||||||
|
save_res<4, 4>(ii+4, jj, 4, fin_res);
|
||||||
|
save_res<4, 4>(ii, jj+4, 8, fin_res);
|
||||||
|
save_res<4, 4>(ii+4, jj+4, 12, fin_res);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int RM, int RN>
|
||||||
|
void gemm_small(int64_t m0, int64_t m, int64_t n0, int64_t n) {
|
||||||
|
int64_t ytiles = (m - m0) / RM;
|
||||||
|
int64_t xtiles = (n - n0) / RN;
|
||||||
|
int64_t tiles = xtiles * ytiles;
|
||||||
|
int64_t duty = (tiles + nth - 1) / nth;
|
||||||
|
int64_t start = duty * ith;
|
||||||
|
int64_t end = start + duty;
|
||||||
|
vec_t vec_A[8], vec_B[8] = {0};
|
||||||
|
vector signed int vec_C[4];
|
||||||
|
acc_t acc_0;
|
||||||
|
|
||||||
|
if (end > tiles)
|
||||||
|
end = tiles;
|
||||||
|
for (int64_t job = start; job < end; ++job) {
|
||||||
|
int64_t ii = m0 + job / xtiles * RM;
|
||||||
|
int64_t jj = n0 + job % xtiles * RN;
|
||||||
|
std::array<int, RM> comparray;
|
||||||
|
vector float res[4] = {0};
|
||||||
|
vector float fin_res[4] = {0};
|
||||||
|
vector float vs[4] = {0};
|
||||||
|
vector float CA[4] = {0};
|
||||||
|
__builtin_prefetch((A+(ii*lda)+0)->qs, 0, 1); // prefetch first value
|
||||||
|
__builtin_prefetch((B+(jj*ldb)+0)->qs, 0, 1); // prefetch first value
|
||||||
|
for (int l = 0; l < k; l++) {
|
||||||
|
__builtin_prefetch((A+(ii*lda)+(l+1))->qs, 0, 1); // prefetch one loop ahead
|
||||||
|
__builtin_prefetch((B+(jj*ldb)+(l+1))->qs, 0, 1); // prefetch one loop ahead
|
||||||
|
__builtin_mma_xxsetaccz(&acc_0);
|
||||||
|
packNormal<int8_t, vector signed char>((A+(ii*lda)+l), lda, RM, 8, (int8_t*)vec_A, false);
|
||||||
|
packNormal<uint8_t, vector unsigned char>((B+(jj*ldb)+l), ldb, RN, 8, (uint8_t*)vec_B, true);
|
||||||
|
for(int x = 0; x < 8; x+=4) {
|
||||||
|
__builtin_mma_xvi8ger4pp(&acc_0, vec_A[x], vec_B[x]);
|
||||||
|
__builtin_mma_xvi8ger4pp(&acc_0, vec_A[x+1], vec_B[x+1]);
|
||||||
|
__builtin_mma_xvi8ger4pp(&acc_0, vec_A[x+2], vec_B[x+2]);
|
||||||
|
__builtin_mma_xvi8ger4pp(&acc_0, vec_A[x+3], vec_B[x+3]);
|
||||||
|
}
|
||||||
|
for (int I = 0; I<RM; I++) {
|
||||||
|
for (int J = 0; J<RN; J++) {
|
||||||
|
*((float*)&vs[I]+J) = (unhalf((A+((ii+I)*lda)+l)->d) * unhalf((B+((jj+J)*ldb)+l)->d));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__builtin_mma_disassemble_acc(vec_C, &acc_0);
|
||||||
|
auto aoffset = A+(ii*lda)+l;
|
||||||
|
for (int i = 0; i < RM; i++) {
|
||||||
|
comparray[i] = 0;
|
||||||
|
int ca = 0;
|
||||||
|
const int8_t *at = aoffset->qs;
|
||||||
|
for (int j = 0; j < 32; j++)
|
||||||
|
ca += (int)*at++;
|
||||||
|
comparray[i] = ca;
|
||||||
|
aoffset += lda;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < RM; i++) {
|
||||||
|
CA[i] = vec_splats((float)(((double)comparray[i]) * -128.0));
|
||||||
|
res[i] = vec_add(vec_ctf(vec_C[i], 0), CA[i]);
|
||||||
|
fin_res[i] = vec_madd(res[i], vs[i], fin_res[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
save_res<RM, RN>(ii, jj, 0, fin_res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int RM, int RN>
|
||||||
|
inline void kernel(int64_t ii, int64_t jj) {
|
||||||
|
if constexpr(RM == 4 && RN == 8) {
|
||||||
|
KERNEL_4x8(ii,jj);
|
||||||
|
} else if constexpr(RM == 8 && RN == 4) {
|
||||||
|
KERNEL_8x4(ii,jj);
|
||||||
|
} else if constexpr(RM == 8 && RN == 8) {
|
||||||
|
KERNEL_8x8(ii,jj);
|
||||||
|
} else {
|
||||||
|
static_assert(false, "RN/RM values not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int RM, int RN>
|
||||||
|
NOINLINE void gemm(int64_t m0, int64_t m, int64_t n0, int64_t n) {
|
||||||
|
int64_t ytiles = (m - m0) / RM;
|
||||||
|
int64_t xtiles = (n - n0) / RN;
|
||||||
|
int64_t tiles = xtiles * ytiles;
|
||||||
|
int64_t duty = (tiles + nth - 1) / nth;
|
||||||
|
int64_t start = duty * ith;
|
||||||
|
int64_t end = start + duty;
|
||||||
|
if (end > tiles)
|
||||||
|
end = tiles;
|
||||||
|
for (int64_t job = start; job < end; ++job) {
|
||||||
|
int64_t ii = m0 + job / xtiles * RM;
|
||||||
|
int64_t jj = n0 + job % xtiles * RN;
|
||||||
|
kernel<RM, RN>(ii, jj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const TA *const A;
|
||||||
|
const TB *const B;
|
||||||
|
TC *C;
|
||||||
|
TA *At;
|
||||||
|
TB *Bt;
|
||||||
|
const int64_t k;
|
||||||
|
const int64_t lda;
|
||||||
|
const int64_t ldb;
|
||||||
|
const int64_t ldc;
|
||||||
|
const int ith;
|
||||||
|
const int nth;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename TA, typename TB, typename TC>
|
template <typename TA, typename TB, typename TC>
|
||||||
class tinyBLAS_PPC {
|
class tinyBLAS_PPC {
|
||||||
public:
|
public:
|
||||||
|
@ -1070,13 +1769,17 @@ class tinyBLAS_PPC {
|
||||||
|
|
||||||
void (tinyBLAS_PPC::*kernel)(int64_t, int64_t);
|
void (tinyBLAS_PPC::*kernel)(int64_t, int64_t);
|
||||||
|
|
||||||
void READ_BLOCK(const float* a, int64_t lda, int rows, int cols, float* vec) {
|
template<typename VA>
|
||||||
|
void packTranspose(const TA* a, int64_t lda, int rows, int cols, TA* vec) {
|
||||||
int64_t i, j;
|
int64_t i, j;
|
||||||
float *aoffset = NULL, *boffset = NULL;
|
TA *aoffset = NULL, *boffset = NULL;
|
||||||
float *aoffset1 = NULL, *aoffset2 = NULL, *aoffset3 = NULL, *aoffset4 = NULL;
|
TA *aoffset1 = NULL, *aoffset2 = NULL, *aoffset3 = NULL, *aoffset4 = NULL;
|
||||||
float *aoffset5 = NULL, *aoffset6 = NULL, *aoffset7 = NULL, *aoffset8 = NULL;
|
TA *aoffset5 = NULL, *aoffset6 = NULL, *aoffset7 = NULL, *aoffset8 = NULL;
|
||||||
|
__vector_pair C1, C2, C3, C4, C5, C6, C7, C8;
|
||||||
aoffset = const_cast<float*>(a);
|
VA c1[2] = {0}, c2[2] = {0}, c3[2] = {0}, c4[2] = {0};
|
||||||
|
VA c5[2] = {0}, c6[2] = {0}, c7[2] = {0}, c8[2] = {0};
|
||||||
|
VA t1, t2, t3, t4, t5, t6, t7, t8;
|
||||||
|
aoffset = const_cast<TA*>(a);
|
||||||
boffset = vec;
|
boffset = vec;
|
||||||
j = (rows >> 3);
|
j = (rows >> 3);
|
||||||
if (j > 0) {
|
if (j > 0) {
|
||||||
|
@ -1092,9 +1795,6 @@ class tinyBLAS_PPC {
|
||||||
aoffset += 8 * lda;
|
aoffset += 8 * lda;
|
||||||
i = (cols >> 3);
|
i = (cols >> 3);
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
__vector_pair C1, C2, C3, C4, C5, C6, C7, C8;
|
|
||||||
vector float c1[2], c2[2], c3[2], c4[2], c5[2], c6[2], c7[2], c8[2];
|
|
||||||
vector float t1, t2, t3, t4, t5, t6, t7, t8;
|
|
||||||
do {
|
do {
|
||||||
C1 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset1);
|
C1 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset1);
|
||||||
C2 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset2);
|
C2 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset2);
|
||||||
|
@ -1174,21 +1874,19 @@ class tinyBLAS_PPC {
|
||||||
} while(i > 0);
|
} while(i > 0);
|
||||||
}
|
}
|
||||||
if (cols & 4) {
|
if (cols & 4) {
|
||||||
vector float c1, c2, c3, c4, c5, c6, c7, c8;
|
c1[0] = vec_xl(0, aoffset1);
|
||||||
vector float t1, t2, t3, t4, t5, t6, t7, t8;
|
c2[0] = vec_xl(0, aoffset2);
|
||||||
c1 = vec_xl(0, aoffset1);
|
c3[0] = vec_xl(0, aoffset3);
|
||||||
c2 = vec_xl(0, aoffset2);
|
c4[0] = vec_xl(0, aoffset4);
|
||||||
c3 = vec_xl(0, aoffset3);
|
c5[0] = vec_xl(0, aoffset5);
|
||||||
c4 = vec_xl(0, aoffset4);
|
c6[0] = vec_xl(0, aoffset6);
|
||||||
c5 = vec_xl(0, aoffset5);
|
c7[0] = vec_xl(0, aoffset7);
|
||||||
c6 = vec_xl(0, aoffset6);
|
c8[0] = vec_xl(0, aoffset8);
|
||||||
c7 = vec_xl(0, aoffset7);
|
|
||||||
c8 = vec_xl(0, aoffset8);
|
|
||||||
|
|
||||||
t1 = vec_mergeh(c1, c2);
|
t1 = vec_mergeh(c1[0], c2[0]);
|
||||||
t2 = vec_mergeh(c3, c4);
|
t2 = vec_mergeh(c3[0], c4[0]);
|
||||||
t3 = vec_mergeh(c5, c6);
|
t3 = vec_mergeh(c5[0], c6[0]);
|
||||||
t4 = vec_mergeh(c7, c8);
|
t4 = vec_mergeh(c7[0], c8[0]);
|
||||||
t5 = vec_xxpermdi(t1, t2, 0);
|
t5 = vec_xxpermdi(t1, t2, 0);
|
||||||
t6 = vec_xxpermdi(t3, t4, 0);
|
t6 = vec_xxpermdi(t3, t4, 0);
|
||||||
t7 = vec_xxpermdi(t1, t2, 3);
|
t7 = vec_xxpermdi(t1, t2, 3);
|
||||||
|
@ -1198,10 +1896,10 @@ class tinyBLAS_PPC {
|
||||||
vec_xst(t7, 0, boffset+8);
|
vec_xst(t7, 0, boffset+8);
|
||||||
vec_xst(t8, 0, boffset+12);
|
vec_xst(t8, 0, boffset+12);
|
||||||
|
|
||||||
t1 = vec_mergel(c1, c2);
|
t1 = vec_mergel(c1[0], c2[0]);
|
||||||
t2 = vec_mergel(c3, c4);
|
t2 = vec_mergel(c3[0], c4[0]);
|
||||||
t3 = vec_mergel(c5, c6);
|
t3 = vec_mergel(c5[0], c6[0]);
|
||||||
t4 = vec_mergel(c7, c8);
|
t4 = vec_mergel(c7[0], c8[0]);
|
||||||
t5 = vec_xxpermdi(t1, t2, 0);
|
t5 = vec_xxpermdi(t1, t2, 0);
|
||||||
t6 = vec_xxpermdi(t3, t4, 0);
|
t6 = vec_xxpermdi(t3, t4, 0);
|
||||||
t7 = vec_xxpermdi(t1, t2, 3);
|
t7 = vec_xxpermdi(t1, t2, 3);
|
||||||
|
@ -1223,9 +1921,6 @@ class tinyBLAS_PPC {
|
||||||
aoffset += 4 * lda;
|
aoffset += 4 * lda;
|
||||||
i = (cols >> 3);
|
i = (cols >> 3);
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
__vector_pair C1, C2, C3, C4;
|
|
||||||
vector float c1[2], c2[2], c3[2], c4[2];
|
|
||||||
vector float t1, t2, t3, t4, t5, t6, t7, t8;
|
|
||||||
do {
|
do {
|
||||||
C1 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset1);
|
C1 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset1);
|
||||||
C2 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset2);
|
C2 = __builtin_vsx_lxvp(0, (__vector_pair*)aoffset2);
|
||||||
|
@ -1272,22 +1967,20 @@ class tinyBLAS_PPC {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cols & 4) {
|
if (cols & 4) {
|
||||||
vector float c1, c2, c3, c4;
|
c1[0] = vec_xl(0, aoffset1);
|
||||||
vector float t1, t2, t3, t4;
|
c2[0] = vec_xl(0, aoffset2);
|
||||||
c1 = vec_xl(0, aoffset1);
|
c3[0] = vec_xl(0, aoffset3);
|
||||||
c2 = vec_xl(0, aoffset2);
|
c4[0] = vec_xl(0, aoffset4);
|
||||||
c3 = vec_xl(0, aoffset3);
|
|
||||||
c4 = vec_xl(0, aoffset4);
|
|
||||||
|
|
||||||
t1 = vec_mergeh(c1, c2);
|
t1 = vec_mergeh(c1[0], c2[0]);
|
||||||
t2 = vec_mergeh(c3, c4);
|
t2 = vec_mergeh(c3[0], c4[0]);
|
||||||
t3 = vec_xxpermdi(t1, t2, 0);
|
t3 = vec_xxpermdi(t1, t2, 0);
|
||||||
t4 = vec_xxpermdi(t1, t2, 3);
|
t4 = vec_xxpermdi(t1, t2, 3);
|
||||||
vec_xst(t3, 0, boffset);
|
vec_xst(t3, 0, boffset);
|
||||||
vec_xst(t4, 0, boffset+4);
|
vec_xst(t4, 0, boffset+4);
|
||||||
|
|
||||||
t1 = vec_mergel(c1, c2);
|
t1 = vec_mergel(c1[0], c2[0]);
|
||||||
t2 = vec_mergel(c3, c4);
|
t2 = vec_mergel(c3[0], c4[0]);
|
||||||
t3 = vec_xxpermdi(t1, t2, 0);
|
t3 = vec_xxpermdi(t1, t2, 0);
|
||||||
t4 = vec_xxpermdi(t1, t2, 3);
|
t4 = vec_xxpermdi(t1, t2, 3);
|
||||||
vec_xst(t3, 0, boffset+8);
|
vec_xst(t3, 0, boffset+8);
|
||||||
|
@ -1299,21 +1992,19 @@ class tinyBLAS_PPC {
|
||||||
aoffset2 = aoffset1 + lda;
|
aoffset2 = aoffset1 + lda;
|
||||||
aoffset3 = aoffset2 + lda;
|
aoffset3 = aoffset2 + lda;
|
||||||
if (cols & 4) {
|
if (cols & 4) {
|
||||||
vector float c1, c2, c3, c4 = {0};
|
c1[0] = vec_xl(0, aoffset1);
|
||||||
vector float t1, t2, t3, t4;
|
c2[0] = vec_xl(0, aoffset2);
|
||||||
c1 = vec_xl(0, aoffset1);
|
c3[0] = vec_xl(0, aoffset3);
|
||||||
c2 = vec_xl(0, aoffset2);
|
|
||||||
c3 = vec_xl(0, aoffset3);
|
|
||||||
|
|
||||||
t1 = vec_mergeh(c1, c2);
|
t1 = vec_mergeh(c1[0], c2[0]);
|
||||||
t2 = vec_mergeh(c3, c4);
|
t2 = vec_mergeh(c3[0], c4[0]);
|
||||||
t3 = vec_xxpermdi(t1, t2, 0);
|
t3 = vec_xxpermdi(t1, t2, 0);
|
||||||
t4 = vec_xxpermdi(t1, t2, 3);
|
t4 = vec_xxpermdi(t1, t2, 3);
|
||||||
vec_xst(t3, 0, boffset);
|
vec_xst(t3, 0, boffset);
|
||||||
vec_xst(t4, 0, boffset+4);
|
vec_xst(t4, 0, boffset+4);
|
||||||
|
|
||||||
t1 = vec_mergel(c1, c2);
|
t1 = vec_mergel(c1[0], c2[0]);
|
||||||
t2 = vec_mergel(c3, c4);
|
t2 = vec_mergel(c3[0], c4[0]);
|
||||||
t3 = vec_xxpermdi(t1, t2, 0);
|
t3 = vec_xxpermdi(t1, t2, 0);
|
||||||
t4 = vec_xxpermdi(t1, t2, 3);
|
t4 = vec_xxpermdi(t1, t2, 3);
|
||||||
vec_xst(t3, 0, boffset+8);
|
vec_xst(t3, 0, boffset+8);
|
||||||
|
@ -1321,14 +2012,13 @@ class tinyBLAS_PPC {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KERNEL_4x4(int64_t ii, int64_t jj) {
|
void KERNEL_4x4(int64_t ii, int64_t jj) {
|
||||||
vec_t vec_A[4], vec_B[4], vec_C[4];
|
vec_t vec_A[4], vec_B[4], vec_C[4];
|
||||||
acc_t acc_0;
|
acc_t acc_0;
|
||||||
__builtin_mma_xxsetaccz(&acc_0);
|
__builtin_mma_xxsetaccz(&acc_0);
|
||||||
for (int l = 0; l < k; l+=4) {
|
for (int l = 0; l < k; l+=4) {
|
||||||
READ_BLOCK(A+(ii*lda)+l, lda, 4, 4, (float*)vec_A);
|
packTranspose<vector float>(A+(ii*lda)+l, lda, 4, 4, (TA*)vec_A);
|
||||||
READ_BLOCK(B+(jj*ldb)+l, ldb, 4, 4, (float*)vec_B);
|
packTranspose<vector float>(B+(jj*ldb)+l, ldb, 4, 4, (TA*)vec_B);
|
||||||
__builtin_mma_xvf32gerpp(&acc_0, vec_A[0], vec_B[0]);
|
__builtin_mma_xvf32gerpp(&acc_0, vec_A[0], vec_B[0]);
|
||||||
__builtin_mma_xvf32gerpp(&acc_0, vec_A[1], vec_B[1]);
|
__builtin_mma_xvf32gerpp(&acc_0, vec_A[1], vec_B[1]);
|
||||||
__builtin_mma_xvf32gerpp(&acc_0, vec_A[2], vec_B[2]);
|
__builtin_mma_xvf32gerpp(&acc_0, vec_A[2], vec_B[2]);
|
||||||
|
@ -1343,8 +2033,8 @@ class tinyBLAS_PPC {
|
||||||
__builtin_mma_xxsetaccz(&acc_0);
|
__builtin_mma_xxsetaccz(&acc_0);
|
||||||
__builtin_mma_xxsetaccz(&acc_1);
|
__builtin_mma_xxsetaccz(&acc_1);
|
||||||
for (int64_t l = 0; l < k; l+=4) {
|
for (int64_t l = 0; l < k; l+=4) {
|
||||||
READ_BLOCK(A+(ii*lda)+l, lda, 4, 4, (float*)vec_A);
|
packTranspose<vector float>(A+(ii*lda)+l, lda, 4, 4, (TA*)vec_A);
|
||||||
READ_BLOCK(B+(jj*ldb)+l, ldb, 8, 4, (float*)vec_B);
|
packTranspose<vector float>(B+(jj*ldb)+l, ldb, 8, 4, (TA*)vec_B);
|
||||||
__builtin_mma_xvf32gerpp(&acc_0, vec_A[0], (vec_t)vec_B[0]);
|
__builtin_mma_xvf32gerpp(&acc_0, vec_A[0], (vec_t)vec_B[0]);
|
||||||
__builtin_mma_xvf32gerpp(&acc_1, vec_A[0], (vec_t)vec_B[1]);
|
__builtin_mma_xvf32gerpp(&acc_1, vec_A[0], (vec_t)vec_B[1]);
|
||||||
__builtin_mma_xvf32gerpp(&acc_0, vec_A[1], (vec_t)vec_B[2]);
|
__builtin_mma_xvf32gerpp(&acc_0, vec_A[1], (vec_t)vec_B[2]);
|
||||||
|
@ -1364,8 +2054,8 @@ class tinyBLAS_PPC {
|
||||||
__builtin_mma_xxsetaccz(&acc_0);
|
__builtin_mma_xxsetaccz(&acc_0);
|
||||||
__builtin_mma_xxsetaccz(&acc_1);
|
__builtin_mma_xxsetaccz(&acc_1);
|
||||||
for (int64_t l = 0; l < k; l+=4) {
|
for (int64_t l = 0; l < k; l+=4) {
|
||||||
READ_BLOCK(A+(ii*lda)+l, lda, 8, 4, (float*)vec_A);
|
packTranspose<vector float>(A+(ii*lda)+l, lda, 8, 4, (TA*)vec_A);
|
||||||
READ_BLOCK(B+(jj*ldb)+l, ldb, 4, 4, (float*)vec_B);
|
packTranspose<vector float>(B+(jj*ldb)+l, ldb, 4, 4, (TA*)vec_B);
|
||||||
__builtin_mma_xvf32gerpp(&acc_0, (vec_t)vec_A[0], vec_B[0]);
|
__builtin_mma_xvf32gerpp(&acc_0, (vec_t)vec_A[0], vec_B[0]);
|
||||||
__builtin_mma_xvf32gerpp(&acc_1, (vec_t)vec_A[1], vec_B[0]);
|
__builtin_mma_xvf32gerpp(&acc_1, (vec_t)vec_A[1], vec_B[0]);
|
||||||
__builtin_mma_xvf32gerpp(&acc_0, (vec_t)vec_A[2], vec_B[1]);
|
__builtin_mma_xvf32gerpp(&acc_0, (vec_t)vec_A[2], vec_B[1]);
|
||||||
|
@ -1387,8 +2077,8 @@ class tinyBLAS_PPC {
|
||||||
__builtin_mma_xxsetaccz(&acc_2);
|
__builtin_mma_xxsetaccz(&acc_2);
|
||||||
__builtin_mma_xxsetaccz(&acc_3);
|
__builtin_mma_xxsetaccz(&acc_3);
|
||||||
for (int l = 0; l < k; l+=8) {
|
for (int l = 0; l < k; l+=8) {
|
||||||
READ_BLOCK(A+(ii*lda)+l, lda, 8, 8, (float*)vec_A);
|
packTranspose<vector float>(A+(ii*lda)+l, lda, 8, 8, (TA*)vec_A);
|
||||||
READ_BLOCK(B+(jj*ldb)+l, ldb, 8, 8, (float*)vec_B);
|
packTranspose<vector float>(B+(jj*ldb)+l, ldb, 8, 8, (TA*)vec_B);
|
||||||
for(int x = 0; x < 16; x+=2) {
|
for(int x = 0; x < 16; x+=2) {
|
||||||
__builtin_mma_xvf32gerpp(&acc_0, (vec_t)vec_A[x], vec_B[x]);
|
__builtin_mma_xvf32gerpp(&acc_0, (vec_t)vec_A[x], vec_B[x]);
|
||||||
__builtin_mma_xvf32gerpp(&acc_1, (vec_t)vec_A[x], vec_B[x+1]);
|
__builtin_mma_xvf32gerpp(&acc_1, (vec_t)vec_A[x], vec_B[x+1]);
|
||||||
|
@ -1571,15 +2261,15 @@ class tinyBLAS_PPC {
|
||||||
vec_t vec_A[4], vec_B[4];
|
vec_t vec_A[4], vec_B[4];
|
||||||
for (int l=0; l<k; l+=4) {
|
for (int l=0; l<k; l+=4) {
|
||||||
if (RN >= 4 && RM == 1) {
|
if (RN >= 4 && RM == 1) {
|
||||||
float* a = const_cast<float*>(A+(ii)*lda+l);
|
TA* a = const_cast<TA*>(A+(ii)*lda+l);
|
||||||
READ_BLOCK(B+(jj*ldb)+l, ldb, 4, 4, (float*)vec_B);
|
packTranspose<vector float>(B+(jj*ldb)+l, ldb, 4, 4, (TA*)vec_B);
|
||||||
vec_A[0] = (vec_t)vec_xl(0,a);
|
vec_A[0] = (vec_t)vec_xl(0,a);
|
||||||
vec_A[1] = (vec_t)vec_splats(*((float*)&vec_A+1));
|
vec_A[1] = (vec_t)vec_splats(*((TA*)&vec_A+1));
|
||||||
vec_A[2] = (vec_t)vec_splats(*((float*)&vec_A+2));
|
vec_A[2] = (vec_t)vec_splats(*((TA*)&vec_A+2));
|
||||||
vec_A[3] = (vec_t)vec_splats(*((float*)&vec_A+3));
|
vec_A[3] = (vec_t)vec_splats(*((TA*)&vec_A+3));
|
||||||
} else {
|
} else {
|
||||||
READ_BLOCK(A+(ii*lda)+l, lda, RM, 4, (float*)vec_A);
|
packTranspose<vector float>(A+(ii*lda)+l, lda, RM, 4, (TA*)vec_A);
|
||||||
READ_BLOCK(B+(jj*ldb)+l, ldb, RN, 4, (float*)vec_B);
|
packTranspose<vector float>(B+(jj*ldb)+l, ldb, RN, 4, (TA*)vec_B);
|
||||||
}
|
}
|
||||||
__builtin_mma_xvf32gerpp(&acc_0, vec_A[0], vec_B[0]);
|
__builtin_mma_xvf32gerpp(&acc_0, vec_A[0], vec_B[0]);
|
||||||
__builtin_mma_xvf32gerpp(&acc_0, vec_A[1], vec_B[1]);
|
__builtin_mma_xvf32gerpp(&acc_0, vec_A[1], vec_B[1]);
|
||||||
|
@ -1589,7 +2279,7 @@ class tinyBLAS_PPC {
|
||||||
__builtin_mma_disassemble_acc(vec_C, &acc_0);
|
__builtin_mma_disassemble_acc(vec_C, &acc_0);
|
||||||
for (int I = 0; I < RM; I++) {
|
for (int I = 0; I < RM; I++) {
|
||||||
for (int J = 0; J < RN; J++) {
|
for (int J = 0; J < RN; J++) {
|
||||||
*((float*)(C+ii+((jj+J)*ldc)+I)) = *((float*)&vec_C[I]+J);
|
*((TC*)(C+ii+((jj+J)*ldc)+I)) = *((TC*)&vec_C[I]+J);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1812,6 +2502,20 @@ bool llamafile_sgemm(const struct ggml_compute_params * params, int64_t m, int64
|
||||||
params->ith, params->nth};
|
params->ith, params->nth};
|
||||||
tb.matmul(m, n);
|
tb.matmul(m, n);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
#elif defined(__MMA__)
|
||||||
|
if (n < 8 && n != 4)
|
||||||
|
return false;
|
||||||
|
if (m < 8 && m != 4)
|
||||||
|
return false;
|
||||||
|
tinyBLAS_Q0_PPC<block_q8_0, block_q8_0, float> tb{
|
||||||
|
k, (const block_q8_0 *)A, lda,
|
||||||
|
(const block_q8_0 *)B, ldb,
|
||||||
|
(float *)C, ldc,
|
||||||
|
params->ith, params->nth};
|
||||||
|
tb.matmul(m, n);
|
||||||
|
return true;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,6 +8,20 @@ if (Vulkan_FOUND)
|
||||||
../../include/ggml-vulkan.h
|
../../include/ggml-vulkan.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Compile a test shader to determine whether GL_KHR_cooperative_matrix is supported.
|
||||||
|
# If it's not, there will be an error to stderr.
|
||||||
|
# If it's supported, set a define to indicate that we should compile those shaders
|
||||||
|
execute_process(COMMAND ${Vulkan_GLSLC_EXECUTABLE} -o - -fshader-stage=compute --target-env=vulkan1.3 "${CMAKE_CURRENT_SOURCE_DIR}/vulkan-shaders/test_coopmat_support.comp"
|
||||||
|
OUTPUT_VARIABLE glslc_output
|
||||||
|
ERROR_VARIABLE glslc_error)
|
||||||
|
|
||||||
|
if (${glslc_error} MATCHES ".*extension not supported: GL_KHR_cooperative_matrix.*")
|
||||||
|
message(STATUS "GL_KHR_cooperative_matrix not supported by glslc")
|
||||||
|
else()
|
||||||
|
message(STATUS "GL_KHR_cooperative_matrix supported by glslc")
|
||||||
|
add_compile_definitions(GGML_VULKAN_COOPMAT_GLSLC_SUPPORT)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Compile a test shader to determine whether GL_NV_cooperative_matrix2 is supported.
|
# Compile a test shader to determine whether GL_NV_cooperative_matrix2 is supported.
|
||||||
# If it's not, there will be an error to stderr.
|
# If it's not, there will be an error to stderr.
|
||||||
# If it's supported, set a define to indicate that we should compile those shaders
|
# If it's supported, set a define to indicate that we should compile those shaders
|
||||||
|
@ -69,11 +83,15 @@ if (Vulkan_FOUND)
|
||||||
|
|
||||||
file(GLOB _ggml_vk_shader_deps "${_ggml_vk_input_dir}/*.comp")
|
file(GLOB _ggml_vk_shader_deps "${_ggml_vk_input_dir}/*.comp")
|
||||||
|
|
||||||
|
if (NOT CMAKE_CROSSCOMPILING)
|
||||||
|
set(_ggml_vk_genshaders_cmd "$<TARGET_FILE_DIR:vulkan-shaders-gen>/${_ggml_vk_genshaders_cmd}")
|
||||||
|
endif ()
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${_ggml_vk_header}
|
OUTPUT ${_ggml_vk_header}
|
||||||
${_ggml_vk_source}
|
${_ggml_vk_source}
|
||||||
|
|
||||||
COMMAND "$<TARGET_FILE_DIR:vulkan-shaders-gen>/${_ggml_vk_genshaders_cmd}"
|
COMMAND ${_ggml_vk_genshaders_cmd}
|
||||||
--glslc ${Vulkan_GLSLC_EXECUTABLE}
|
--glslc ${Vulkan_GLSLC_EXECUTABLE}
|
||||||
--input-dir ${_ggml_vk_input_dir}
|
--input-dir ${_ggml_vk_input_dir}
|
||||||
--output-dir ${_ggml_vk_output_dir}
|
--output-dir ${_ggml_vk_output_dir}
|
||||||
|
|
|
@ -1645,6 +1645,7 @@ static void ggml_vk_load_shaders(vk_device& device) {
|
||||||
#undef CREATE_MM2
|
#undef CREATE_MM2
|
||||||
} else
|
} else
|
||||||
#endif // defined(VK_NV_cooperative_matrix2) && defined(GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT)
|
#endif // defined(VK_NV_cooperative_matrix2) && defined(GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT)
|
||||||
|
#if defined(VK_KHR_cooperative_matrix) && defined(GGML_VULKAN_COOPMAT_GLSLC_SUPPORT)
|
||||||
if (device->coopmat_support) {
|
if (device->coopmat_support) {
|
||||||
// Create 6 variants, {s,m,l}x{unaligned,aligned}
|
// Create 6 variants, {s,m,l}x{unaligned,aligned}
|
||||||
#define CREATE_MM(PIPELINE_NAME, NAMELC, F16ACC, WG_DENOMS, WARPTILE, PUSHCONST, PARAMCOUNT, ID) \
|
#define CREATE_MM(PIPELINE_NAME, NAMELC, F16ACC, WG_DENOMS, WARPTILE, PUSHCONST, PARAMCOUNT, ID) \
|
||||||
|
@ -1739,7 +1740,9 @@ static void ggml_vk_load_shaders(vk_device& device) {
|
||||||
}
|
}
|
||||||
#undef CREATE_MM2
|
#undef CREATE_MM2
|
||||||
#undef CREATE_MM
|
#undef CREATE_MM
|
||||||
} else if (device->fp16) {
|
} else
|
||||||
|
#endif // defined(VK_KHR_cooperative_matrix) && defined(GGML_VULKAN_COOPMAT_GLSLC_SUPPORT)
|
||||||
|
if (device->fp16) {
|
||||||
// Create 6 variants, {s,m,l}x{unaligned,aligned}
|
// Create 6 variants, {s,m,l}x{unaligned,aligned}
|
||||||
#define CREATE_MM(PIPELINE_NAME, NAMELC, F16ACC, WG_DENOMS, WARPTILE, PUSHCONST, PARAMCOUNT, ID) \
|
#define CREATE_MM(PIPELINE_NAME, NAMELC, F16ACC, WG_DENOMS, WARPTILE, PUSHCONST, PARAMCOUNT, ID) \
|
||||||
if (device->mul_mat ## ID ## _l) \
|
if (device->mul_mat ## ID ## _l) \
|
||||||
|
@ -2242,6 +2245,7 @@ static vk_device ggml_vk_get_device(size_t idx) {
|
||||||
last_struct = (VkBaseOutStructure *)&subgroup_size_control_features;
|
last_struct = (VkBaseOutStructure *)&subgroup_size_control_features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(VK_KHR_cooperative_matrix)
|
||||||
VkPhysicalDeviceCooperativeMatrixFeaturesKHR coopmat_features;
|
VkPhysicalDeviceCooperativeMatrixFeaturesKHR coopmat_features;
|
||||||
coopmat_features.pNext = nullptr;
|
coopmat_features.pNext = nullptr;
|
||||||
coopmat_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR;
|
coopmat_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR;
|
||||||
|
@ -2251,6 +2255,7 @@ static vk_device ggml_vk_get_device(size_t idx) {
|
||||||
last_struct->pNext = (VkBaseOutStructure *)&coopmat_features;
|
last_struct->pNext = (VkBaseOutStructure *)&coopmat_features;
|
||||||
last_struct = (VkBaseOutStructure *)&coopmat_features;
|
last_struct = (VkBaseOutStructure *)&coopmat_features;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(VK_NV_cooperative_matrix2)
|
#if defined(VK_NV_cooperative_matrix2)
|
||||||
VkPhysicalDeviceCooperativeMatrix2FeaturesNV coopmat2_features {};
|
VkPhysicalDeviceCooperativeMatrix2FeaturesNV coopmat2_features {};
|
||||||
|
@ -2283,7 +2288,9 @@ static vk_device ggml_vk_get_device(size_t idx) {
|
||||||
device_extensions.push_back("VK_EXT_subgroup_size_control");
|
device_extensions.push_back("VK_EXT_subgroup_size_control");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(VK_KHR_cooperative_matrix)
|
||||||
device->coopmat_support = device->coopmat_support && coopmat_features.cooperativeMatrix;
|
device->coopmat_support = device->coopmat_support && coopmat_features.cooperativeMatrix;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (coopmat2_support) {
|
if (coopmat2_support) {
|
||||||
#if defined(VK_NV_cooperative_matrix2) && defined(GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT)
|
#if defined(VK_NV_cooperative_matrix2) && defined(GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT)
|
||||||
|
@ -2376,6 +2383,7 @@ static vk_device ggml_vk_get_device(size_t idx) {
|
||||||
device_extensions.push_back("VK_KHR_shader_float16_int8");
|
device_extensions.push_back("VK_KHR_shader_float16_int8");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(VK_KHR_cooperative_matrix)
|
||||||
if (device->coopmat_support) {
|
if (device->coopmat_support) {
|
||||||
// Query supported shapes
|
// Query supported shapes
|
||||||
std::vector<VkCooperativeMatrixPropertiesKHR> cm_props;
|
std::vector<VkCooperativeMatrixPropertiesKHR> cm_props;
|
||||||
|
@ -2442,7 +2450,7 @@ static vk_device ggml_vk_get_device(size_t idx) {
|
||||||
if (device->coopmat_support) {
|
if (device->coopmat_support) {
|
||||||
device_extensions.push_back("VK_KHR_cooperative_matrix");
|
device_extensions.push_back("VK_KHR_cooperative_matrix");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
device->name = GGML_VK_NAME + std::to_string(idx);
|
device->name = GGML_VK_NAME + std::to_string(idx);
|
||||||
|
|
||||||
device_create_info = {
|
device_create_info = {
|
||||||
|
@ -2553,9 +2561,11 @@ static void ggml_vk_print_gpu_info(size_t idx) {
|
||||||
fp16_storage = true;
|
fp16_storage = true;
|
||||||
} else if (strcmp("VK_KHR_shader_float16_int8", properties.extensionName) == 0) {
|
} else if (strcmp("VK_KHR_shader_float16_int8", properties.extensionName) == 0) {
|
||||||
fp16_compute = true;
|
fp16_compute = true;
|
||||||
|
#if defined(GGML_VULKAN_COOPMAT_GLSLC_SUPPORT)
|
||||||
} else if (strcmp("VK_KHR_cooperative_matrix", properties.extensionName) == 0 &&
|
} else if (strcmp("VK_KHR_cooperative_matrix", properties.extensionName) == 0 &&
|
||||||
!getenv("GGML_VK_DISABLE_COOPMAT")) {
|
!getenv("GGML_VK_DISABLE_COOPMAT")) {
|
||||||
coopmat_support = true;
|
coopmat_support = true;
|
||||||
|
#endif
|
||||||
#if defined(GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT)
|
#if defined(GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT)
|
||||||
} else if (strcmp("VK_NV_cooperative_matrix2", properties.extensionName) == 0 &&
|
} else if (strcmp("VK_NV_cooperative_matrix2", properties.extensionName) == 0 &&
|
||||||
!getenv("GGML_VK_DISABLE_COOPMAT2")) {
|
!getenv("GGML_VK_DISABLE_COOPMAT2")) {
|
||||||
|
@ -2593,6 +2603,7 @@ static void ggml_vk_print_gpu_info(size_t idx) {
|
||||||
// Pointer to the last chain element
|
// Pointer to the last chain element
|
||||||
VkBaseOutStructure * last_struct = (VkBaseOutStructure *)&vk12_features;
|
VkBaseOutStructure * last_struct = (VkBaseOutStructure *)&vk12_features;
|
||||||
|
|
||||||
|
#if defined(GGML_VULKAN_COOPMAT_GLSLC_SUPPORT)
|
||||||
VkPhysicalDeviceCooperativeMatrixFeaturesKHR coopmat_features;
|
VkPhysicalDeviceCooperativeMatrixFeaturesKHR coopmat_features;
|
||||||
coopmat_features.pNext = nullptr;
|
coopmat_features.pNext = nullptr;
|
||||||
coopmat_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR;
|
coopmat_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR;
|
||||||
|
@ -2608,6 +2619,7 @@ static void ggml_vk_print_gpu_info(size_t idx) {
|
||||||
fp16 = fp16 && vk12_features.shaderFloat16;
|
fp16 = fp16 && vk12_features.shaderFloat16;
|
||||||
|
|
||||||
coopmat_support = coopmat_support && coopmat_features.cooperativeMatrix;
|
coopmat_support = coopmat_support && coopmat_features.cooperativeMatrix;
|
||||||
|
#endif
|
||||||
|
|
||||||
std::string matrix_cores = coopmat2_support ? "NV_coopmat2" : coopmat_support ? "KHR_coopmat" : "none";
|
std::string matrix_cores = coopmat2_support ? "NV_coopmat2" : coopmat_support ? "KHR_coopmat" : "none";
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#version 460
|
||||||
|
|
||||||
|
#extension GL_KHR_cooperative_matrix : require
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
}
|
|
@ -342,9 +342,11 @@ void process_shaders() {
|
||||||
matmul_shaders(true, matmul_id, false, false, false);
|
matmul_shaders(true, matmul_id, false, false, false);
|
||||||
matmul_shaders(true, matmul_id, false, false, true);
|
matmul_shaders(true, matmul_id, false, false, true);
|
||||||
|
|
||||||
|
#if defined(GGML_VULKAN_COOPMAT_GLSLC_SUPPORT)
|
||||||
// Coopmat, fp32acc and fp16acc
|
// Coopmat, fp32acc and fp16acc
|
||||||
matmul_shaders(true, matmul_id, true, false, false);
|
matmul_shaders(true, matmul_id, true, false, false);
|
||||||
matmul_shaders(true, matmul_id, true, false, true);
|
matmul_shaders(true, matmul_id, true, false, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT)
|
#if defined(GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT)
|
||||||
// Coopmat2, fp32acc and fp16acc
|
// Coopmat2, fp32acc and fp16acc
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue