Merge branch 'master' into concedo_experimental
# Conflicts: # ggml.h
This commit is contained in:
commit
923184f2e8
5 changed files with 456 additions and 285 deletions
|
@ -15,7 +15,7 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
float tensor_sum_elements(struct ggml_tensor * tensor) {
|
float tensor_sum_elements(const ggml_tensor * tensor) {
|
||||||
float sum = 0;
|
float sum = 0;
|
||||||
if (tensor->type==GGML_TYPE_F32) {
|
if (tensor->type==GGML_TYPE_F32) {
|
||||||
for (int j = 0; j < tensor->ne[1]; j++) {
|
for (int j = 0; j < tensor->ne[1]; j++) {
|
||||||
|
@ -27,21 +27,15 @@ float tensor_sum_elements(struct ggml_tensor * tensor) {
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tensor_dump(const ggml_tensor * tensor, const char * name) {
|
||||||
|
printf("%15s: type = %i (%5s) ne = %5d x %5d x %5d, nb = (%5li, %5li, %5li) - ", name,
|
||||||
|
tensor->type, ggml_type_name(tensor->type),
|
||||||
|
(int) tensor->ne[0], (int) tensor->ne[1], (int) tensor->ne[2], tensor->nb[0], tensor->nb[1], tensor->nb[2]);
|
||||||
|
float sum = tensor_sum_elements(tensor);
|
||||||
|
printf("Sum of tensor %s is %6.2f\n", name, sum);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
#define TENSOR_DUMP(tensor) tensor_dump(tensor, #tensor)
|
||||||
These are mapping to unknown
|
|
||||||
GGML_TYPE_I8,
|
|
||||||
GGML_TYPE_I16,
|
|
||||||
GGML_TYPE_I32,
|
|
||||||
GGML_TYPE_COUNT,
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define TENSOR_TYPE_AS_STR(TYPE) TYPE == GGML_TYPE_F32 ? "FP32" : TYPE == GGML_TYPE_F16 ? "FP16" : TYPE == GGML_TYPE_Q4_0 ? "Q4_0" : TYPE == GGML_TYPE_Q4_1 ? "Q4_1" : "UNKNOWN"
|
|
||||||
|
|
||||||
#define TENSOR_DUMP(TENSOR) printf("%15s: type = %i (%5s) ne = %5d x %5d x %5d, nb = (%5li, %5li, %5li) - ", #TENSOR, \
|
|
||||||
TENSOR->type,TENSOR_TYPE_AS_STR(TENSOR->type),\
|
|
||||||
(int) TENSOR->ne[0], (int) TENSOR->ne[1], (int) TENSOR->ne[2], TENSOR->nb[0], TENSOR->nb[1], TENSOR->nb[2]); \
|
|
||||||
{ float sum = tensor_sum_elements(TENSOR); printf("Sum of tensor %s is %6.2f\n",#TENSOR, sum); }
|
|
||||||
|
|
||||||
struct benchmark_params_struct {
|
struct benchmark_params_struct {
|
||||||
int32_t n_threads = 1;
|
int32_t n_threads = 1;
|
||||||
|
@ -59,8 +53,6 @@ void print_usage(int /*argc*/, char ** argv, struct benchmark_params_struct para
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char ** argv) {
|
int main(int argc, char ** argv) {
|
||||||
|
|
||||||
|
|
||||||
struct benchmark_params_struct benchmark_params;
|
struct benchmark_params_struct benchmark_params;
|
||||||
|
|
||||||
bool invalid_param = false;
|
bool invalid_param = false;
|
||||||
|
@ -84,12 +76,12 @@ int main(int argc, char ** argv) {
|
||||||
print_usage(argc, argv, benchmark_params);
|
print_usage(argc, argv, benchmark_params);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (invalid_param) {
|
if (invalid_param) {
|
||||||
fprintf(stderr, "error: invalid parameter for argument: %s\n", arg.c_str());
|
fprintf(stderr, "error: invalid parameter for argument: %s\n", arg.c_str());
|
||||||
print_usage(argc, argv, benchmark_params);
|
print_usage(argc, argv, benchmark_params);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "%s: build = %d (%s)\n", __func__, BUILD_NUMBER, BUILD_COMMIT);
|
fprintf(stderr, "%s: build = %d (%s)\n", __func__, BUILD_NUMBER, BUILD_COMMIT);
|
||||||
printf("Starting Test\n");
|
printf("Starting Test\n");
|
||||||
|
@ -216,9 +208,8 @@ int main(int argc, char ** argv) {
|
||||||
// Let's use the F32 result from above as a reference for the q4_0 multiplication
|
// Let's use the F32 result from above as a reference for the q4_0 multiplication
|
||||||
float sum_of_F32_reference = tensor_sum_elements(gf.nodes[0]);
|
float sum_of_F32_reference = tensor_sum_elements(gf.nodes[0]);
|
||||||
|
|
||||||
|
printf("Iteration;NThreads; SizeX; SizeY; SizeZ; Required_FLOPS; Elapsed_u_Seconds; gigaFLOPS\n");
|
||||||
printf("Iteration;NThreads; SizeX; SizeY; SizeZ; Required_FLOPS; Elapsed_u_Seconds; FLOPS_per_u_Second\n");
|
printf("=====================================================================================\n");
|
||||||
printf("==============================================================================================\n");
|
|
||||||
|
|
||||||
for (int i=0;i<benchmark_params.n_iterations ;i++) {
|
for (int i=0;i<benchmark_params.n_iterations ;i++) {
|
||||||
|
|
||||||
|
@ -227,12 +218,12 @@ int main(int argc, char ** argv) {
|
||||||
ggml_graph_compute(ctx, &gf31);
|
ggml_graph_compute(ctx, &gf31);
|
||||||
long long int stop = ggml_time_us();
|
long long int stop = ggml_time_us();
|
||||||
long long int usec = stop-start;
|
long long int usec = stop-start;
|
||||||
float flops_per_usec = (1.0f*flops_per_matrix)/usec;
|
double gflops = (double)(flops_per_matrix)/usec/1000.0;
|
||||||
printf("%9i;%8i;%6i;%6i;%6i;%15lli;%18lli;%19.2f\n",
|
printf("%9i;%8i;%6i;%6i;%6i;%15lli;%18lli;%10.2f\n",
|
||||||
i,
|
i,
|
||||||
gf31.n_threads,
|
gf31.n_threads,
|
||||||
sizex, sizey, sizez, flops_per_matrix,
|
sizex, sizey, sizez, flops_per_matrix,
|
||||||
usec,flops_per_usec);
|
usec,gflops);
|
||||||
|
|
||||||
#ifdef VERBOSE_DEBUGGING
|
#ifdef VERBOSE_DEBUGGING
|
||||||
TENSOR_DUMP("res",gf31.nodes[0])
|
TENSOR_DUMP("res",gf31.nodes[0])
|
||||||
|
@ -256,7 +247,5 @@ int main(int argc, char ** argv) {
|
||||||
|
|
||||||
// Running a different graph computation to make sure we override the CPU cache lines
|
// Running a different graph computation to make sure we override the CPU cache lines
|
||||||
ggml_graph_compute(ctx, &gf32);
|
ggml_graph_compute(ctx, &gf32);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#if defined(__APPLE__) && defined(__MACH__)
|
#if defined(__APPLE__) && defined(__MACH__)
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -28,21 +29,21 @@
|
||||||
|
|
||||||
int32_t get_num_physical_cores() {
|
int32_t get_num_physical_cores() {
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
std::ifstream cpuinfo("/proc/cpuinfo");
|
// enumerate the set of thread siblings, num entries is num cores
|
||||||
|
std::unordered_set<std::string> siblings;
|
||||||
|
for (uint32_t cpu=0; cpu < UINT32_MAX; ++cpu) {
|
||||||
|
std::ifstream thread_siblings("/sys/devices/system/cpu"
|
||||||
|
+ std::to_string(cpu) + "/topology/thread_siblings");
|
||||||
|
if (!thread_siblings.is_open()) {
|
||||||
|
break; // no more cpus
|
||||||
|
}
|
||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(cpuinfo, line)) {
|
if (std::getline(thread_siblings, line)) {
|
||||||
std::size_t pos = line.find("cpu cores");
|
siblings.insert(line);
|
||||||
if (pos != std::string::npos) {
|
|
||||||
pos = line.find(": ", pos);
|
|
||||||
if (pos != std::string::npos) {
|
|
||||||
try {
|
|
||||||
// Extract the number and return it
|
|
||||||
return static_cast<int32_t>(std::stoul(line.substr(pos + 2)));
|
|
||||||
} catch (const std::invalid_argument &) {
|
|
||||||
// Ignore if we could not parse
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (siblings.size() > 0) {
|
||||||
|
return static_cast<int32_t>(siblings.size());
|
||||||
}
|
}
|
||||||
#elif defined(__APPLE__) && defined(__MACH__)
|
#elif defined(__APPLE__) && defined(__MACH__)
|
||||||
int32_t num_physical_cores;
|
int32_t num_physical_cores;
|
||||||
|
|
154
ggml-cuda.cu
154
ggml-cuda.cu
|
@ -83,7 +83,8 @@ typedef struct {
|
||||||
} block_q8_0;
|
} block_q8_0;
|
||||||
static_assert(sizeof(block_q8_0) == sizeof(float) + QK8_0, "wrong q8_0 block size/padding");
|
static_assert(sizeof(block_q8_0) == sizeof(float) + QK8_0, "wrong q8_0 block size/padding");
|
||||||
|
|
||||||
#define CUDA_DMMV_BLOCK_SIZE 32
|
#define CUDA_DEQUANTIZE_BLOCK_SIZE 256
|
||||||
|
#define CUDA_DMMV_BLOCK_SIZE 32 // dmmv = dequantize_mul_mat_vec
|
||||||
|
|
||||||
static __device__ void dequantize_q4_0(const void * vx, const int ib, const int iqs, float & v0, float & v1){
|
static __device__ void dequantize_q4_0(const void * vx, const int ib, const int iqs, float & v0, float & v1){
|
||||||
const block_q4_0 * x = (const block_q4_0 *) vx;
|
const block_q4_0 * x = (const block_q4_0 *) vx;
|
||||||
|
@ -170,104 +171,23 @@ static __device__ void convert_f16(const void * vx, const int ib, const int iqs,
|
||||||
v1 = __half2float(x[ib + 1]);
|
v1 = __half2float(x[ib + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __global__ void dequantize_block_q4_0(const void * vx, float * y) {
|
template <int qk, int qr, dequantize_kernel_t dequantize_kernel>
|
||||||
static const int qk = QK4_0;
|
static __global__ void dequantize_block(const void * vx, float * y, const int k) {
|
||||||
|
const int i = blockDim.x*blockIdx.x + 2*threadIdx.x;
|
||||||
|
|
||||||
const block_q4_0 * x = (const block_q4_0 *) vx;
|
if (i >= k) {
|
||||||
|
return;
|
||||||
const int i = blockIdx.x;
|
|
||||||
|
|
||||||
const float d = x[i].d;
|
|
||||||
|
|
||||||
for (int j = 0; j < qk/2; ++j) {
|
|
||||||
const int x0 = (x[i].qs[j] & 0xf) - 8;
|
|
||||||
const int x1 = (x[i].qs[j] >> 4) - 8;
|
|
||||||
|
|
||||||
y[i*qk + j + 0 ] = x0*d;
|
|
||||||
y[i*qk + j + qk/2] = x1*d;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static __global__ void dequantize_block_q4_1(const void * vx, float * y) {
|
const int ib = i/qk; // block index
|
||||||
static const int qk = QK4_1;
|
const int iqs = (i%qk)/qr; // quant index
|
||||||
|
const int iybs = i - i%qk; // y block start index
|
||||||
|
const int y_offset = qr == 1 ? 1 : qk/2;
|
||||||
|
|
||||||
const block_q4_1 * x = (const block_q4_1 *) vx;
|
// dequantize
|
||||||
|
float & v0 = y[iybs + iqs + 0];
|
||||||
const int i = blockIdx.x;
|
float & v1 = y[iybs + iqs + y_offset];
|
||||||
|
dequantize_kernel(vx, ib, iqs, v0, v1);
|
||||||
const float d = x[i].d;
|
|
||||||
const float m = x[i].m;
|
|
||||||
|
|
||||||
for (int j = 0; j < qk/2; ++j) {
|
|
||||||
const int x0 = (x[i].qs[j] & 0xf);
|
|
||||||
const int x1 = (x[i].qs[j] >> 4);
|
|
||||||
|
|
||||||
y[i*qk + j + 0 ] = x0*d + m;
|
|
||||||
y[i*qk + j + qk/2] = x1*d + m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static __global__ void dequantize_block_q5_0(const void * vx, float * y) {
|
|
||||||
static const int qk = QK5_0;
|
|
||||||
|
|
||||||
const block_q5_0 * x = (const block_q5_0 *) vx;
|
|
||||||
|
|
||||||
const int i = blockIdx.x;
|
|
||||||
|
|
||||||
const float d = x[i].d;
|
|
||||||
|
|
||||||
uint32_t qh;
|
|
||||||
memcpy(&qh, x[i].qh, sizeof(qh));
|
|
||||||
|
|
||||||
for (int j = 0; j < qk/2; ++j) {
|
|
||||||
const uint8_t xh_0 = ((qh >> (j + 0)) << 4) & 0x10;
|
|
||||||
const uint8_t xh_1 = ((qh >> (j + 12)) ) & 0x10;
|
|
||||||
|
|
||||||
const int32_t x0 = ((x[i].qs[j] & 0xf) | xh_0) - 16;
|
|
||||||
const int32_t x1 = ((x[i].qs[j] >> 4) | xh_1) - 16;
|
|
||||||
|
|
||||||
y[i*qk + j + 0 ] = x0*d;
|
|
||||||
y[i*qk + j + qk/2] = x1*d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static __global__ void dequantize_block_q5_1(const void * vx, float * y) {
|
|
||||||
static const int qk = QK5_1;
|
|
||||||
|
|
||||||
const block_q5_1 * x = (const block_q5_1 *) vx;
|
|
||||||
|
|
||||||
const int i = blockIdx.x;
|
|
||||||
|
|
||||||
const float d = x[i].d;
|
|
||||||
const float m = x[i].m;
|
|
||||||
|
|
||||||
uint32_t qh;
|
|
||||||
memcpy(&qh, x[i].qh, sizeof(qh));
|
|
||||||
|
|
||||||
for (int j = 0; j < qk/2; ++j) {
|
|
||||||
const uint8_t xh_0 = ((qh >> (j + 0)) << 4) & 0x10;
|
|
||||||
const uint8_t xh_1 = ((qh >> (j + 12)) ) & 0x10;
|
|
||||||
|
|
||||||
const int x0 = (x[i].qs[j] & 0xf) | xh_0;
|
|
||||||
const int x1 = (x[i].qs[j] >> 4) | xh_1;
|
|
||||||
|
|
||||||
y[i*qk + j + 0 ] = x0*d + m;
|
|
||||||
y[i*qk + j + qk/2] = x1*d + m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static __global__ void dequantize_block_q8_0(const void * vx, float * y) {
|
|
||||||
static const int qk = QK8_0;
|
|
||||||
|
|
||||||
const block_q8_0 * x = (const block_q8_0 *) vx;
|
|
||||||
|
|
||||||
const int i = blockIdx.x;
|
|
||||||
|
|
||||||
const float d = x[i].d;
|
|
||||||
|
|
||||||
for (int j = 0; j < qk; ++j) {
|
|
||||||
y[i*qk + j] = x[i].qs[j]*d;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int block_size, int qk, int qr, dequantize_kernel_t dequantize_kernel>
|
template <int block_size, int qk, int qr, dequantize_kernel_t dequantize_kernel>
|
||||||
|
@ -308,29 +228,29 @@ static __global__ void dequantize_mul_mat_vec(const void * vx, const float * y,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dequantize_row_q4_0_cuda(const void * vx, float * y, int k, cudaStream_t stream) {
|
static void dequantize_row_q4_0_cuda(const void * vx, float * y, const int k, cudaStream_t stream) {
|
||||||
const int nb = k / QK4_0;
|
const int num_blocks = (k + CUDA_DEQUANTIZE_BLOCK_SIZE - 1) / CUDA_DEQUANTIZE_BLOCK_SIZE;
|
||||||
dequantize_block_q4_0<<<nb, 1, 0, stream>>>(vx, y);
|
dequantize_block<QK4_0, QR4_0, dequantize_q4_0><<<num_blocks, CUDA_DEQUANTIZE_BLOCK_SIZE, 0, stream>>>(vx, y, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dequantize_row_q4_1_cuda(const void * vx, float * y, int k, cudaStream_t stream) {
|
static void dequantize_row_q4_1_cuda(const void * vx, float * y, const int k, cudaStream_t stream) {
|
||||||
const int nb = k / QK4_1;
|
const int num_blocks = (k + CUDA_DEQUANTIZE_BLOCK_SIZE - 1) / CUDA_DEQUANTIZE_BLOCK_SIZE;
|
||||||
dequantize_block_q4_1<<<nb, 1, 0, stream>>>(vx, y);
|
dequantize_block<QK4_1, QR4_1, dequantize_q4_1><<<num_blocks, CUDA_DEQUANTIZE_BLOCK_SIZE, 0, stream>>>(vx, y, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dequantize_row_q5_0_cuda(const void * vx, float * y, int k, cudaStream_t stream) {
|
static void dequantize_row_q5_0_cuda(const void * vx, float * y, const int k, cudaStream_t stream) {
|
||||||
const int nb = k / QK5_0;
|
const int num_blocks = (k + CUDA_DEQUANTIZE_BLOCK_SIZE - 1) / CUDA_DEQUANTIZE_BLOCK_SIZE;
|
||||||
dequantize_block_q5_0<<<nb, 1, 0, stream>>>(vx, y);
|
dequantize_block<QK5_0, QR5_0, dequantize_q5_0><<<num_blocks, CUDA_DEQUANTIZE_BLOCK_SIZE, 0, stream>>>(vx, y, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dequantize_row_q5_1_cuda(const void * vx, float * y, int k, cudaStream_t stream) {
|
static void dequantize_row_q5_1_cuda(const void * vx, float * y, const int k, cudaStream_t stream) {
|
||||||
const int nb = k / QK5_1;
|
const int num_blocks = (k + CUDA_DEQUANTIZE_BLOCK_SIZE - 1) / CUDA_DEQUANTIZE_BLOCK_SIZE;
|
||||||
dequantize_block_q5_1<<<nb, 1, 0, stream>>>(vx, y);
|
dequantize_block<QK5_1, QR5_1, dequantize_q5_1><<<num_blocks, CUDA_DEQUANTIZE_BLOCK_SIZE, 0, stream>>>(vx, y, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dequantize_row_q8_0_cuda(const void * vx, float * y, int k, cudaStream_t stream) {
|
static void dequantize_row_q8_0_cuda(const void * vx, float * y, const int k, cudaStream_t stream) {
|
||||||
const int nb = k / QK8_0;
|
const int num_blocks = (k + CUDA_DEQUANTIZE_BLOCK_SIZE - 1) / CUDA_DEQUANTIZE_BLOCK_SIZE;
|
||||||
dequantize_block_q8_0<<<nb, 1, 0, stream>>>(vx, y);
|
dequantize_block<QK8_0, QR8_0, dequantize_q8_0><<<num_blocks, CUDA_DEQUANTIZE_BLOCK_SIZE, 0, stream>>>(vx, y, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dequantize_mul_mat_vec_q4_0_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
static void dequantize_mul_mat_vec_q4_0_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
||||||
|
@ -363,17 +283,9 @@ static void dequantize_mul_mat_vec_q8_0_cuda(const void * vx, const float * y, f
|
||||||
<<<nrows, CUDA_DMMV_BLOCK_SIZE, 0, stream>>>(vx, y, dst, ncols);
|
<<<nrows, CUDA_DMMV_BLOCK_SIZE, 0, stream>>>(vx, y, dst, ncols);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: optimize
|
static void convert_fp16_to_fp32_cuda(const void * vx, float * y, const int k, cudaStream_t stream) {
|
||||||
static __global__ void convert_fp16_to_fp32(const void * vx, float * y) {
|
const int num_blocks = (k + CUDA_DEQUANTIZE_BLOCK_SIZE - 1) / CUDA_DEQUANTIZE_BLOCK_SIZE;
|
||||||
const half * x = (const half *) vx;
|
dequantize_block<32, 1, convert_f16><<<num_blocks, CUDA_DEQUANTIZE_BLOCK_SIZE, 0, stream>>>(vx, y, k);
|
||||||
|
|
||||||
const int i = blockIdx.x;
|
|
||||||
|
|
||||||
y[i] = __half2float(x[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void convert_fp16_to_fp32_cuda(const void * x, float * y, int k, cudaStream_t stream) {
|
|
||||||
convert_fp16_to_fp32<<<k, 1, 0, stream>>>(x, y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void convert_mul_mat_vec_f16_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
static void convert_mul_mat_vec_f16_cuda(const void * vx, const float * y, float * dst, const int ncols, const int nrows, cudaStream_t stream) {
|
||||||
|
|
430
ggml.c
430
ggml.c
|
@ -578,7 +578,63 @@ static inline __m128i packNibbles( __m256i bytes )
|
||||||
return _mm_packus_epi16( r0, r1 );
|
return _mm_packus_epi16( r0, r1 );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#elif defined(__AVX__)
|
||||||
|
// spread 32 bits to 32 bytes { 0x00, 0xFF }
|
||||||
|
static inline __m256i bytes_from_bits_32(const uint8_t * x) {
|
||||||
|
uint32_t x32;
|
||||||
|
memcpy(&x32, x, sizeof(uint32_t));
|
||||||
|
const __m128i shuf_maskl = _mm_set_epi64x(0x0101010101010101, 0x0000000000000000);
|
||||||
|
const __m128i shuf_maskh = _mm_set_epi64x(0x0303030303030303, 0x0202020202020202);
|
||||||
|
__m128i bytesl = _mm_shuffle_epi8(_mm_set1_epi32(x32), shuf_maskl);
|
||||||
|
__m128i bytesh = _mm_shuffle_epi8(_mm_set1_epi32(x32), shuf_maskh);
|
||||||
|
const __m128i bit_mask = _mm_set1_epi64x(0x7fbfdfeff7fbfdfe);
|
||||||
|
bytesl = _mm_or_si128(bytesl, bit_mask);
|
||||||
|
bytesh = _mm_or_si128(bytesh, bit_mask);
|
||||||
|
bytesl = _mm_cmpeq_epi8(bytesl, _mm_set1_epi64x(-1));
|
||||||
|
bytesh = _mm_cmpeq_epi8(bytesh, _mm_set1_epi64x(-1));
|
||||||
|
return _mm256_set_m128i(bytesh, bytesl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpack 32 4-bit fields into 32 bytes
|
||||||
|
// The output vector contains 32 bytes, each one in [ 0 .. 15 ] interval
|
||||||
|
static inline __m256i bytes_from_nibbles_32(const uint8_t * rsi)
|
||||||
|
{
|
||||||
|
// Load 16 bytes from memory
|
||||||
|
__m128i tmpl = _mm_loadu_si128((const __m128i *)rsi);
|
||||||
|
__m128i tmph = _mm_srli_epi16(tmpl, 4);
|
||||||
|
const __m128i lowMask = _mm_set1_epi8(0xF);
|
||||||
|
tmpl = _mm_and_si128(lowMask, tmpl);
|
||||||
|
tmph = _mm_and_si128(lowMask, tmph);
|
||||||
|
return _mm256_set_m128i(tmph, tmpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add int16_t pairwise and return as float vector
|
||||||
|
static inline __m256 sum_i16_pairs_float(const __m128i xh, const __m128i xl) {
|
||||||
|
const __m128i ones = _mm_set1_epi16(1);
|
||||||
|
const __m128i summed_pairsl = _mm_madd_epi16(ones, xl);
|
||||||
|
const __m128i summed_pairsh = _mm_madd_epi16(ones, xh);
|
||||||
|
const __m256i summed_pairs = _mm256_set_m128i(summed_pairsh, summed_pairsl);
|
||||||
|
return _mm256_cvtepi32_ps(summed_pairs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// multiply int8_t, add results pairwise twice and return as float vector
|
||||||
|
static inline __m256 mul_sum_i8_pairs_float(const __m256i x, const __m256i y) {
|
||||||
|
const __m128i xl = _mm256_castsi256_si128(x);
|
||||||
|
const __m128i xh = _mm256_extractf128_si256(x, 1);
|
||||||
|
const __m128i yl = _mm256_castsi256_si128(y);
|
||||||
|
const __m128i yh = _mm256_extractf128_si256(y, 1);
|
||||||
|
// Get absolute values of x vectors
|
||||||
|
const __m128i axl = _mm_sign_epi8(xl, xl);
|
||||||
|
const __m128i axh = _mm_sign_epi8(xh, xh);
|
||||||
|
// Sign the values of the y vectors
|
||||||
|
const __m128i syl = _mm_sign_epi8(yl, xl);
|
||||||
|
const __m128i syh = _mm_sign_epi8(yh, xh);
|
||||||
|
// Perform multiplication and create 16-bit values
|
||||||
|
const __m128i dotl = _mm_maddubs_epi16(axl, syl);
|
||||||
|
const __m128i doth = _mm_maddubs_epi16(axh, syh);
|
||||||
|
return sum_i16_pairs_float(doth, dotl);
|
||||||
|
}
|
||||||
|
|
||||||
static inline __m128i packNibbles( __m128i bytes1, __m128i bytes2 )
|
static inline __m128i packNibbles( __m128i bytes1, __m128i bytes2 )
|
||||||
{
|
{
|
||||||
// Move bits within 16-bit lanes from 0000_abcd_0000_efgh into 0000_0000_abcd_efgh
|
// Move bits within 16-bit lanes from 0000_abcd_0000_efgh into 0000_0000_abcd_efgh
|
||||||
|
@ -2385,7 +2441,7 @@ static void ggml_vec_dot_q4_1_q8_1(const int n, float * restrict s, const void *
|
||||||
}
|
}
|
||||||
|
|
||||||
*s = vaddvq_f32(sumv0) + vaddvq_f32(sumv1) + summs;
|
*s = vaddvq_f32(sumv0) + vaddvq_f32(sumv1) + summs;
|
||||||
#elif defined(__AVX2__)
|
#elif defined(__AVX2__) || defined(__AVX__)
|
||||||
// Initialize accumulator with zeros
|
// Initialize accumulator with zeros
|
||||||
__m256 acc = _mm256_setzero_ps();
|
__m256 acc = _mm256_setzero_ps();
|
||||||
|
|
||||||
|
@ -2411,7 +2467,11 @@ static void ggml_vec_dot_q4_1_q8_1(const int n, float * restrict s, const void *
|
||||||
const __m256 xy = mul_sum_i8_pairs_float(bx, by);
|
const __m256 xy = mul_sum_i8_pairs_float(bx, by);
|
||||||
|
|
||||||
// Accumulate d0*d1*x*y
|
// Accumulate d0*d1*x*y
|
||||||
|
#if defined(__AVX2__)
|
||||||
acc = _mm256_fmadd_ps( d0d1, xy, acc );
|
acc = _mm256_fmadd_ps( d0d1, xy, acc );
|
||||||
|
#else
|
||||||
|
acc = _mm256_add_ps( _mm256_mul_ps( d0d1, xy ), acc );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
*s = hsum_float_8(acc) + summs;
|
*s = hsum_float_8(acc) + summs;
|
||||||
|
@ -2622,6 +2682,37 @@ static void ggml_vec_dot_q5_0_q8_0(const int n, float * restrict s, const void *
|
||||||
acc = _mm256_fmadd_ps(d, q, acc);
|
acc = _mm256_fmadd_ps(d, q, acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*s = hsum_float_8(acc);
|
||||||
|
#elif defined(__AVX__)
|
||||||
|
// Initialize accumulator with zeros
|
||||||
|
__m256 acc = _mm256_setzero_ps();
|
||||||
|
__m128i mask = _mm_set1_epi8((char)0xF0);
|
||||||
|
|
||||||
|
// Main loop
|
||||||
|
for (int i = 0; i < nb; i++) {
|
||||||
|
/* Compute combined scale for the block */
|
||||||
|
const __m256 d = _mm256_mul_ps(_mm256_set1_ps(GGML_FP16_TO_FP32(x[i].d)), _mm256_broadcast_ss(&y[i].d));
|
||||||
|
|
||||||
|
__m256i bx = bytes_from_nibbles_32(x[i].qs);
|
||||||
|
const __m256i bxhi = bytes_from_bits_32(x[i].qh);
|
||||||
|
__m128i bxhil = _mm256_castsi256_si128(bxhi);
|
||||||
|
__m128i bxhih = _mm256_extractf128_si256(bxhi, 1);
|
||||||
|
bxhil = _mm_andnot_si128(bxhil, mask);
|
||||||
|
bxhih = _mm_andnot_si128(bxhih, mask);
|
||||||
|
__m128i bxl = _mm256_castsi256_si128(bx);
|
||||||
|
__m128i bxh = _mm256_extractf128_si256(bx, 1);
|
||||||
|
bxl = _mm_or_si128(bxl, bxhil);
|
||||||
|
bxh = _mm_or_si128(bxh, bxhih);
|
||||||
|
bx = _mm256_set_m128i(bxh, bxl);
|
||||||
|
|
||||||
|
const __m256i by = _mm256_loadu_si256((const __m256i *)y[i].qs);
|
||||||
|
|
||||||
|
const __m256 q = mul_sum_i8_pairs_float(bx, by);
|
||||||
|
|
||||||
|
/* Multiply q with scale and accumulate */
|
||||||
|
acc = _mm256_add_ps(_mm256_mul_ps(d, q), acc);
|
||||||
|
}
|
||||||
|
|
||||||
*s = hsum_float_8(acc);
|
*s = hsum_float_8(acc);
|
||||||
#else
|
#else
|
||||||
// scalar
|
// scalar
|
||||||
|
@ -2850,6 +2941,40 @@ static void ggml_vec_dot_q5_1_q8_1(const int n, float * restrict s, const void *
|
||||||
acc = _mm256_fmadd_ps(q, _mm256_mul_ps(dx, dy), acc);
|
acc = _mm256_fmadd_ps(q, _mm256_mul_ps(dx, dy), acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*s = hsum_float_8(acc) + summs;
|
||||||
|
#elif defined(__AVX__)
|
||||||
|
// Initialize accumulator with zeros
|
||||||
|
__m256 acc = _mm256_setzero_ps();
|
||||||
|
__m128i mask = _mm_set1_epi8(0x10);
|
||||||
|
|
||||||
|
float summs = 0.0f;
|
||||||
|
|
||||||
|
// Main loop
|
||||||
|
for (int i = 0; i < nb; i++) {
|
||||||
|
const __m256 dx = _mm256_set1_ps(GGML_FP16_TO_FP32(x[i].d));
|
||||||
|
|
||||||
|
summs += GGML_FP16_TO_FP32(x[i].m) * y[i].s;
|
||||||
|
|
||||||
|
__m256i bx = bytes_from_nibbles_32(x[i].qs);
|
||||||
|
const __m256i bxhi = bytes_from_bits_32(x[i].qh);
|
||||||
|
__m128i bxhil = _mm256_castsi256_si128(bxhi);
|
||||||
|
__m128i bxhih = _mm256_extractf128_si256(bxhi, 1);
|
||||||
|
bxhil = _mm_and_si128(bxhil, mask);
|
||||||
|
bxhih = _mm_and_si128(bxhih, mask);
|
||||||
|
__m128i bxl = _mm256_castsi256_si128(bx);
|
||||||
|
__m128i bxh = _mm256_extractf128_si256(bx, 1);
|
||||||
|
bxl = _mm_or_si128(bxl, bxhil);
|
||||||
|
bxh = _mm_or_si128(bxh, bxhih);
|
||||||
|
bx = _mm256_set_m128i(bxh, bxl);
|
||||||
|
|
||||||
|
const __m256 dy = _mm256_broadcast_ss(&y[i].d);
|
||||||
|
const __m256i by = _mm256_loadu_si256((const __m256i *)y[i].qs);
|
||||||
|
|
||||||
|
const __m256 q = mul_sum_i8_pairs_float(bx, by);
|
||||||
|
|
||||||
|
acc = _mm256_add_ps(_mm256_mul_ps(q, _mm256_mul_ps(dx, dy)), acc);
|
||||||
|
}
|
||||||
|
|
||||||
*s = hsum_float_8(acc) + summs;
|
*s = hsum_float_8(acc) + summs;
|
||||||
#else
|
#else
|
||||||
// scalar
|
// scalar
|
||||||
|
@ -2940,7 +3065,7 @@ static void ggml_vec_dot_q8_0_q8_0(const int n, float * restrict s, const void *
|
||||||
}
|
}
|
||||||
|
|
||||||
*s = vaddvq_f32(sumv0) + vaddvq_f32(sumv1);
|
*s = vaddvq_f32(sumv0) + vaddvq_f32(sumv1);
|
||||||
#elif defined(__AVX2__)
|
#elif defined(__AVX2__) || defined(__AVX__)
|
||||||
// Initialize accumulator with zeros
|
// Initialize accumulator with zeros
|
||||||
__m256 acc = _mm256_setzero_ps();
|
__m256 acc = _mm256_setzero_ps();
|
||||||
|
|
||||||
|
@ -2954,7 +3079,11 @@ static void ggml_vec_dot_q8_0_q8_0(const int n, float * restrict s, const void *
|
||||||
const __m256 q = mul_sum_i8_pairs_float(bx, by);
|
const __m256 q = mul_sum_i8_pairs_float(bx, by);
|
||||||
|
|
||||||
// Multiply q with scale and accumulate
|
// Multiply q with scale and accumulate
|
||||||
|
#if defined(__AVX2__)
|
||||||
acc = _mm256_fmadd_ps( d, q, acc );
|
acc = _mm256_fmadd_ps( d, q, acc );
|
||||||
|
#else
|
||||||
|
acc = _mm256_add_ps( _mm256_mul_ps( d, q ), acc );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
*s = hsum_float_8(acc);
|
*s = hsum_float_8(acc);
|
||||||
|
@ -3845,6 +3974,20 @@ size_t ggml_set_scratch(struct ggml_context * ctx, struct ggml_scratch scratch)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IMPORTANT:
|
||||||
|
// when creating "opt" tensors, always save and load the scratch buffer
|
||||||
|
// this is an error prone process, but it is necessary to support inplace
|
||||||
|
// operators when using scratch buffers
|
||||||
|
// TODO: implement a better way
|
||||||
|
void ggml_scratch_save(struct ggml_context * ctx) {
|
||||||
|
ctx->scratch_save = ctx->scratch;
|
||||||
|
ctx->scratch.data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ggml_scratch_load(struct ggml_context * ctx) {
|
||||||
|
ctx->scratch = ctx->scratch_save;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct ggml_tensor * ggml_new_tensor_impl(
|
struct ggml_tensor * ggml_new_tensor_impl(
|
||||||
|
@ -4016,12 +4159,11 @@ struct ggml_tensor * ggml_new_tensor_4d(
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ggml_tensor * ggml_new_i32(struct ggml_context * ctx, int32_t value) {
|
struct ggml_tensor * ggml_new_i32(struct ggml_context * ctx, int32_t value) {
|
||||||
ctx->scratch_save = ctx->scratch;
|
ggml_scratch_save(ctx);
|
||||||
ctx->scratch.data = NULL;
|
|
||||||
|
|
||||||
struct ggml_tensor * result = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, 1);
|
struct ggml_tensor * result = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, 1);
|
||||||
|
|
||||||
ctx->scratch = ctx->scratch_save;
|
ggml_scratch_load(ctx);
|
||||||
|
|
||||||
ggml_set_i32(result, value);
|
ggml_set_i32(result, value);
|
||||||
|
|
||||||
|
@ -4029,12 +4171,11 @@ struct ggml_tensor * ggml_new_i32(struct ggml_context * ctx, int32_t value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ggml_tensor * ggml_new_f32(struct ggml_context * ctx, float value) {
|
struct ggml_tensor * ggml_new_f32(struct ggml_context * ctx, float value) {
|
||||||
ctx->scratch_save = ctx->scratch;
|
ggml_scratch_save(ctx);
|
||||||
ctx->scratch.data = NULL;
|
|
||||||
|
|
||||||
struct ggml_tensor * result = ggml_new_tensor_1d(ctx, GGML_TYPE_F32, 1);
|
struct ggml_tensor * result = ggml_new_tensor_1d(ctx, GGML_TYPE_F32, 1);
|
||||||
|
|
||||||
ctx->scratch = ctx->scratch_save;
|
ggml_scratch_load(ctx);
|
||||||
|
|
||||||
ggml_set_f32(result, value);
|
ggml_set_f32(result, value);
|
||||||
|
|
||||||
|
@ -4463,13 +4604,19 @@ struct ggml_tensor * ggml_acc_impl(
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ggml_tensor * result = inplace ? ggml_view_tensor(ctx, a) : ggml_dup_tensor(ctx, a);
|
struct ggml_tensor * result = inplace ? ggml_view_tensor(ctx, a) : ggml_dup_tensor(ctx, a);
|
||||||
|
|
||||||
|
ggml_scratch_save(ctx);
|
||||||
|
|
||||||
struct ggml_tensor * c = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, 5);
|
struct ggml_tensor * c = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, 5);
|
||||||
|
|
||||||
((int32_t *) c->data)[0] = nb1;
|
((int32_t *) c->data)[0] = nb1;
|
||||||
((int32_t *) c->data)[1] = nb2;
|
((int32_t *) c->data)[1] = nb2;
|
||||||
((int32_t *) c->data)[2] = nb3;
|
((int32_t *) c->data)[2] = nb3;
|
||||||
((int32_t *) c->data)[3] = offset;
|
((int32_t *) c->data)[3] = offset;
|
||||||
((int32_t *) c->data)[4] = inplace ? 1 : 0;
|
((int32_t *) c->data)[4] = inplace ? 1 : 0;
|
||||||
|
|
||||||
|
ggml_scratch_load(ctx);
|
||||||
|
|
||||||
result->op = GGML_OP_ACC;
|
result->op = GGML_OP_ACC;
|
||||||
result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL;
|
result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL;
|
||||||
result->src0 = a;
|
result->src0 = a;
|
||||||
|
@ -5266,13 +5413,19 @@ struct ggml_tensor * ggml_set_impl(
|
||||||
|
|
||||||
// make a view of the destination
|
// make a view of the destination
|
||||||
struct ggml_tensor * result = inplace ? ggml_view_tensor(ctx, a) : ggml_dup_tensor(ctx, a);
|
struct ggml_tensor * result = inplace ? ggml_view_tensor(ctx, a) : ggml_dup_tensor(ctx, a);
|
||||||
|
|
||||||
|
ggml_scratch_save(ctx);
|
||||||
|
|
||||||
struct ggml_tensor * c = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, 5);
|
struct ggml_tensor * c = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, 5);
|
||||||
|
|
||||||
(( int32_t * ) c->data)[0] = nb1;
|
(( int32_t * ) c->data)[0] = nb1;
|
||||||
(( int32_t * ) c->data)[1] = nb2;
|
(( int32_t * ) c->data)[1] = nb2;
|
||||||
(( int32_t * ) c->data)[2] = nb3;
|
(( int32_t * ) c->data)[2] = nb3;
|
||||||
(( int32_t * ) c->data)[3] = offset;
|
(( int32_t * ) c->data)[3] = offset;
|
||||||
(( int32_t * ) c->data)[4] = inplace ? 1 : 0;
|
(( int32_t * ) c->data)[4] = inplace ? 1 : 0;
|
||||||
|
|
||||||
|
ggml_scratch_load(ctx);
|
||||||
|
|
||||||
result->op = GGML_OP_SET;
|
result->op = GGML_OP_SET;
|
||||||
result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL;
|
result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL;
|
||||||
result->src0 = a;
|
result->src0 = a;
|
||||||
|
@ -5876,10 +6029,16 @@ struct ggml_tensor * ggml_diag_mask_inf_impl(
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ggml_tensor * result = inplace ? ggml_view_tensor(ctx, a) : ggml_dup_tensor(ctx, a);
|
struct ggml_tensor * result = inplace ? ggml_view_tensor(ctx, a) : ggml_dup_tensor(ctx, a);
|
||||||
|
|
||||||
|
ggml_scratch_save(ctx);
|
||||||
|
|
||||||
struct ggml_tensor * b = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, 2);
|
struct ggml_tensor * b = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, 2);
|
||||||
|
|
||||||
((int32_t *) b->data)[0] = n_past;
|
((int32_t *) b->data)[0] = n_past;
|
||||||
((int32_t *) b->data)[1] = inplace ? 1 : 0;
|
((int32_t *) b->data)[1] = inplace ? 1 : 0;
|
||||||
|
|
||||||
|
ggml_scratch_load(ctx);
|
||||||
|
|
||||||
result->op = GGML_OP_DIAG_MASK_INF;
|
result->op = GGML_OP_DIAG_MASK_INF;
|
||||||
result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL;
|
result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL;
|
||||||
result->src0 = a;
|
result->src0 = a;
|
||||||
|
@ -5917,11 +6076,17 @@ struct ggml_tensor * ggml_diag_mask_zero_impl(
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ggml_tensor * result = inplace ? ggml_view_tensor(ctx, a) : ggml_dup_tensor(ctx, a);
|
struct ggml_tensor * result = inplace ? ggml_view_tensor(ctx, a) : ggml_dup_tensor(ctx, a);
|
||||||
|
|
||||||
|
ggml_scratch_save(ctx);
|
||||||
|
|
||||||
struct ggml_tensor * b = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, 2);
|
struct ggml_tensor * b = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, 2);
|
||||||
ggml_set_name(b, "n_past, inplace");
|
ggml_set_name(b, "n_past, inplace");
|
||||||
|
|
||||||
((int32_t *) b->data)[0] = n_past;
|
((int32_t *) b->data)[0] = n_past;
|
||||||
((int32_t *) b->data)[1] = inplace ? 1 : 0;
|
((int32_t *) b->data)[1] = inplace ? 1 : 0;
|
||||||
|
|
||||||
|
ggml_scratch_load(ctx);
|
||||||
|
|
||||||
result->op = GGML_OP_DIAG_MASK_ZERO;
|
result->op = GGML_OP_DIAG_MASK_ZERO;
|
||||||
result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL;
|
result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL;
|
||||||
result->src0 = a;
|
result->src0 = a;
|
||||||
|
@ -5996,11 +6161,16 @@ struct ggml_tensor * ggml_rope_impl(
|
||||||
|
|
||||||
struct ggml_tensor * result = inplace ? ggml_view_tensor(ctx, a) : ggml_dup_tensor(ctx, a);
|
struct ggml_tensor * result = inplace ? ggml_view_tensor(ctx, a) : ggml_dup_tensor(ctx, a);
|
||||||
|
|
||||||
|
ggml_scratch_save(ctx);
|
||||||
|
|
||||||
struct ggml_tensor * b = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, 3);
|
struct ggml_tensor * b = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, 3);
|
||||||
|
|
||||||
((int32_t *) b->data)[0] = n_past;
|
((int32_t *) b->data)[0] = n_past;
|
||||||
((int32_t *) b->data)[1] = n_dims;
|
((int32_t *) b->data)[1] = n_dims;
|
||||||
((int32_t *) b->data)[2] = mode;
|
((int32_t *) b->data)[2] = mode;
|
||||||
|
|
||||||
|
ggml_scratch_load(ctx);
|
||||||
|
|
||||||
result->op = GGML_OP_ROPE;
|
result->op = GGML_OP_ROPE;
|
||||||
result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL;
|
result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL;
|
||||||
result->src0 = a;
|
result->src0 = a;
|
||||||
|
@ -6045,11 +6215,16 @@ struct ggml_tensor * ggml_rope_back(
|
||||||
|
|
||||||
struct ggml_tensor * result = ggml_dup_tensor(ctx, a);
|
struct ggml_tensor * result = ggml_dup_tensor(ctx, a);
|
||||||
|
|
||||||
|
ggml_scratch_save(ctx);
|
||||||
|
|
||||||
struct ggml_tensor * b = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, 3);
|
struct ggml_tensor * b = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, 3);
|
||||||
|
ggml_set_name(b, "n_past, n_dims, mode");
|
||||||
|
|
||||||
((int32_t *) b->data)[0] = n_past;
|
((int32_t *) b->data)[0] = n_past;
|
||||||
((int32_t *) b->data)[1] = n_dims;
|
((int32_t *) b->data)[1] = n_dims;
|
||||||
((int32_t *) b->data)[2] = mode;
|
((int32_t *) b->data)[2] = mode;
|
||||||
ggml_set_name(b, "n_past, n_dims, mode");
|
|
||||||
|
ggml_scratch_load(ctx);
|
||||||
|
|
||||||
result->op = GGML_OP_ROPE_BACK;
|
result->op = GGML_OP_ROPE_BACK;
|
||||||
result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL;
|
result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL;
|
||||||
|
@ -6078,10 +6253,15 @@ struct ggml_tensor * ggml_alibi(
|
||||||
//struct ggml_tensor * result = inplace ? ggml_view_tensor(ctx, a) : ggml_dup_tensor(ctx, a);
|
//struct ggml_tensor * result = inplace ? ggml_view_tensor(ctx, a) : ggml_dup_tensor(ctx, a);
|
||||||
struct ggml_tensor * result = ggml_view_tensor(ctx, a);
|
struct ggml_tensor * result = ggml_view_tensor(ctx, a);
|
||||||
|
|
||||||
|
ggml_scratch_save(ctx);
|
||||||
|
|
||||||
struct ggml_tensor * b = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, 2);
|
struct ggml_tensor * b = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, 2);
|
||||||
|
|
||||||
((int32_t *) b->data)[0] = n_past;
|
((int32_t *) b->data)[0] = n_past;
|
||||||
((int32_t *) b->data)[1] = n_head;
|
((int32_t *) b->data)[1] = n_head;
|
||||||
|
|
||||||
|
ggml_scratch_load(ctx);
|
||||||
|
|
||||||
result->op = GGML_OP_ALIBI;
|
result->op = GGML_OP_ALIBI;
|
||||||
result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL;
|
result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL;
|
||||||
result->src0 = a;
|
result->src0 = a;
|
||||||
|
@ -10416,18 +10596,26 @@ static void ggml_compute_forward_diag_mask_f32(
|
||||||
assert(src1->type == GGML_TYPE_I32);
|
assert(src1->type == GGML_TYPE_I32);
|
||||||
assert(ggml_nelements(src1) == 2);
|
assert(ggml_nelements(src1) == 2);
|
||||||
|
|
||||||
if (params->type == GGML_TASK_INIT || params->type == GGML_TASK_FINALIZE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int ith = params->ith;
|
const int ith = params->ith;
|
||||||
const int nth = params->nth;
|
const int nth = params->nth;
|
||||||
|
|
||||||
const int n_past = ((int32_t *) src1->data)[0];
|
const int n_past = ((int32_t *) src1->data)[0];
|
||||||
const bool inplace = (bool)((int32_t *) src1->data)[1];
|
const bool inplace = (bool)((int32_t *) src1->data)[1];
|
||||||
|
assert(n_past >= 0);
|
||||||
|
|
||||||
if (!inplace) {
|
if (!inplace && (params->type == GGML_TASK_INIT)) {
|
||||||
ggml_compute_forward_dup_same_cont(params, src0, dst);
|
// memcpy needs to be synchronized across threads to avoid race conditions.
|
||||||
|
// => do it in INIT phase
|
||||||
|
GGML_ASSERT(ggml_nelements(dst) == ggml_nelements(src0));
|
||||||
|
GGML_ASSERT(ggml_is_contiguous(dst) && ggml_is_contiguous(src0));
|
||||||
|
memcpy(
|
||||||
|
((char *) dst->data),
|
||||||
|
((char *) src0->data),
|
||||||
|
ggml_nbytes(dst));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params->type == GGML_TASK_INIT || params->type == GGML_TASK_FINALIZE) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle transposed/permuted matrices
|
// TODO: handle transposed/permuted matrices
|
||||||
|
@ -10592,6 +10780,8 @@ static void ggml_compute_forward_alibi_f32(
|
||||||
const int n_past = ((int32_t *) src1->data)[0];
|
const int n_past = ((int32_t *) src1->data)[0];
|
||||||
const int n_head = ((int32_t *) src1->data)[1];
|
const int n_head = ((int32_t *) src1->data)[1];
|
||||||
|
|
||||||
|
assert(n_past >= 0);
|
||||||
|
|
||||||
const int ne0 = src0->ne[0]; // all_seq_len = n_past + ne1
|
const int ne0 = src0->ne[0]; // all_seq_len = n_past + ne1
|
||||||
const int ne1 = src0->ne[1]; // seq_len_without_past
|
const int ne1 = src0->ne[1]; // seq_len_without_past
|
||||||
//const int ne2 = src0->ne[2]; // n_head -> this is k
|
//const int ne2 = src0->ne[2]; // n_head -> this is k
|
||||||
|
@ -10653,6 +10843,8 @@ static void ggml_compute_forward_alibi_f16(
|
||||||
const int n_past = ((int32_t *) src1->data)[0];
|
const int n_past = ((int32_t *) src1->data)[0];
|
||||||
const int n_head = ((int32_t *) src1->data)[1];
|
const int n_head = ((int32_t *) src1->data)[1];
|
||||||
|
|
||||||
|
assert(n_past >= 0);
|
||||||
|
|
||||||
const int ne0 = src0->ne[0]; // all_seq_len = n_past + ne1
|
const int ne0 = src0->ne[0]; // all_seq_len = n_past + ne1
|
||||||
const int ne1 = src0->ne[1]; // seq_len_without_past
|
const int ne1 = src0->ne[1]; // seq_len_without_past
|
||||||
//const int ne2 = src0->ne[2]; // n_head -> this is k
|
//const int ne2 = src0->ne[2]; // n_head -> this is k
|
||||||
|
@ -10749,28 +10941,34 @@ static void ggml_compute_forward_rope_f32(
|
||||||
const int n_dims = ((int32_t *) src1->data)[1];
|
const int n_dims = ((int32_t *) src1->data)[1];
|
||||||
const int mode = ((int32_t *) src1->data)[2];
|
const int mode = ((int32_t *) src1->data)[2];
|
||||||
|
|
||||||
//const int64_t ne0 = src0->ne[0];
|
assert(n_past >= 0);
|
||||||
const int64_t ne1 = src0->ne[1];
|
|
||||||
const int64_t ne2 = src0->ne[2];
|
|
||||||
const int64_t ne3 = src0->ne[3];
|
|
||||||
|
|
||||||
const int nb0 = src0->nb[0];
|
const size_t nb00 = src0->nb[0];
|
||||||
const int nb1 = src0->nb[1];
|
const size_t nb01 = src0->nb[1];
|
||||||
const int nb2 = src0->nb[2];
|
const size_t nb02 = src0->nb[2];
|
||||||
const int nb3 = src0->nb[3];
|
const size_t nb03 = src0->nb[3];
|
||||||
|
|
||||||
|
const int64_t ne0 = dst->ne[0];
|
||||||
|
const int64_t ne1 = dst->ne[1];
|
||||||
|
const int64_t ne2 = dst->ne[2];
|
||||||
|
const int64_t ne3 = dst->ne[3];
|
||||||
|
|
||||||
|
const size_t nb0 = dst->nb[0];
|
||||||
|
const size_t nb1 = dst->nb[1];
|
||||||
|
const size_t nb2 = dst->nb[2];
|
||||||
|
const size_t nb3 = dst->nb[3];
|
||||||
|
|
||||||
//printf("ne0: %d, ne1: %d, ne2: %d, ne3: %d\n", ne0, ne1, ne2, ne3);
|
//printf("ne0: %d, ne1: %d, ne2: %d, ne3: %d\n", ne0, ne1, ne2, ne3);
|
||||||
//printf("n_past = %d, ne2 = %d\n", n_past, ne2);
|
//printf("n_past = %d, ne2 = %d\n", n_past, ne2);
|
||||||
|
|
||||||
GGML_ASSERT(nb0 == sizeof(float));
|
GGML_ASSERT(nb00 == sizeof(float));
|
||||||
|
|
||||||
const int ith = params->ith;
|
const int ith = params->ith;
|
||||||
const int nth = params->nth;
|
const int nth = params->nth;
|
||||||
|
|
||||||
const int nr = ggml_nrows(src0);
|
const int nr = ggml_nrows(dst);
|
||||||
const int nc = src0->ne[0];
|
|
||||||
|
|
||||||
GGML_ASSERT(n_dims <= nc);
|
GGML_ASSERT(n_dims <= ne0);
|
||||||
GGML_ASSERT(n_dims % 2 == 0);
|
GGML_ASSERT(n_dims % 2 == 0);
|
||||||
|
|
||||||
// rows per thread
|
// rows per thread
|
||||||
|
@ -10789,21 +10987,21 @@ static void ggml_compute_forward_rope_f32(
|
||||||
|
|
||||||
for (int64_t i3 = 0; i3 < ne3; i3++) {
|
for (int64_t i3 = 0; i3 < ne3; i3++) {
|
||||||
for (int64_t i2 = ((mode & 1) == 0 ? 0 : n_past); i2 < ne2; i2++) {
|
for (int64_t i2 = ((mode & 1) == 0 ? 0 : n_past); i2 < ne2; i2++) {
|
||||||
const int p = ((mode & 1) == 0 ? n_past + i2 : i2);
|
const int64_t p = ((mode & 1) == 0 ? n_past + i2 : i2);
|
||||||
for (int64_t i1 = 0; i1 < ne1; i1++) {
|
for (int64_t i1 = 0; i1 < ne1; i1++) {
|
||||||
if (ir++ < ir0) continue;
|
if (ir++ < ir0) continue;
|
||||||
if (ir > ir1) break;
|
if (ir > ir1) break;
|
||||||
|
|
||||||
float theta = (float)p;
|
float theta = (float)p;
|
||||||
|
|
||||||
for (int i0 = 0; i0 < n_dims; i0 += 2) {
|
if (!is_neox) {
|
||||||
|
for (int64_t i0 = 0; i0 < ne0; i0 += 2) {
|
||||||
const float cos_theta = cosf(theta);
|
const float cos_theta = cosf(theta);
|
||||||
const float sin_theta = sinf(theta);
|
const float sin_theta = sinf(theta);
|
||||||
|
|
||||||
theta *= theta_scale;
|
theta *= theta_scale;
|
||||||
|
|
||||||
if (!is_neox) {
|
const float * const src = (float *)((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00);
|
||||||
const float * const src = (float *)((char *) src0->data + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
|
||||||
float * dst_data = (float *)((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
float * dst_data = (float *)((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
||||||
|
|
||||||
const float x0 = src[0];
|
const float x0 = src[0];
|
||||||
|
@ -10811,9 +11009,21 @@ static void ggml_compute_forward_rope_f32(
|
||||||
|
|
||||||
dst_data[0] = x0*cos_theta - x1*sin_theta;
|
dst_data[0] = x0*cos_theta - x1*sin_theta;
|
||||||
dst_data[1] = x0*sin_theta + x1*cos_theta;
|
dst_data[1] = x0*sin_theta + x1*cos_theta;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const float * const src = (float *)((char *) src0->data + i3*nb3 + i2*nb2 + i1*nb1 + (i0/2)*nb0);
|
// TODO: this is probably wrong, but I can't figure it out ..
|
||||||
float * dst_data = (float *)((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 + (i0/2)*nb0);
|
// ref: https://github.com/huggingface/transformers/blob/main/src/transformers/models/gpt_neox/modeling_gpt_neox.py#LL251C1-L294C28
|
||||||
|
for (int64_t ib = 0; ib < ne0/n_dims; ++ib) {
|
||||||
|
for (int64_t ic = 0; ic < n_dims; ic += 2) {
|
||||||
|
const float cos_theta = cosf(theta);
|
||||||
|
const float sin_theta = sinf(theta);
|
||||||
|
|
||||||
|
theta *= theta_scale;
|
||||||
|
|
||||||
|
const int64_t i0 = ib*n_dims + ic/2;
|
||||||
|
|
||||||
|
const float * const src = (float *)((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00);
|
||||||
|
float * dst_data = (float *)((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
||||||
|
|
||||||
const float x0 = src[0];
|
const float x0 = src[0];
|
||||||
const float x1 = src[n_dims/2];
|
const float x1 = src[n_dims/2];
|
||||||
|
@ -10825,6 +11035,7 @@ static void ggml_compute_forward_rope_f32(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ggml_compute_forward_rope_f16(
|
static void ggml_compute_forward_rope_f16(
|
||||||
|
@ -10843,15 +11054,22 @@ static void ggml_compute_forward_rope_f16(
|
||||||
const int n_dims = ((int32_t *) src1->data)[1];
|
const int n_dims = ((int32_t *) src1->data)[1];
|
||||||
const int mode = ((int32_t *) src1->data)[2];
|
const int mode = ((int32_t *) src1->data)[2];
|
||||||
|
|
||||||
//const int64_t ne0 = src0->ne[0];
|
assert(n_past >= 0);
|
||||||
const int64_t ne1 = src0->ne[1];
|
|
||||||
const int64_t ne2 = src0->ne[2];
|
|
||||||
const int64_t ne3 = src0->ne[3];
|
|
||||||
|
|
||||||
const int nb0 = src0->nb[0];
|
const size_t nb00 = src0->nb[0];
|
||||||
const int nb1 = src0->nb[1];
|
const size_t nb01 = src0->nb[1];
|
||||||
const int nb2 = src0->nb[2];
|
const size_t nb02 = src0->nb[2];
|
||||||
const int nb3 = src0->nb[3];
|
const size_t nb03 = src0->nb[3];
|
||||||
|
|
||||||
|
const int64_t ne0 = dst->ne[0];
|
||||||
|
const int64_t ne1 = dst->ne[1];
|
||||||
|
const int64_t ne2 = dst->ne[2];
|
||||||
|
const int64_t ne3 = dst->ne[3];
|
||||||
|
|
||||||
|
const size_t nb0 = dst->nb[0];
|
||||||
|
const size_t nb1 = dst->nb[1];
|
||||||
|
const size_t nb2 = dst->nb[2];
|
||||||
|
const size_t nb3 = dst->nb[3];
|
||||||
|
|
||||||
//printf("ne0: %d, ne1: %d, ne2: %d, ne3: %d\n", ne0, ne1, ne2, ne3);
|
//printf("ne0: %d, ne1: %d, ne2: %d, ne3: %d\n", ne0, ne1, ne2, ne3);
|
||||||
//printf("n_past = %d, ne2 = %d\n", n_past, ne2);
|
//printf("n_past = %d, ne2 = %d\n", n_past, ne2);
|
||||||
|
@ -10861,10 +11079,9 @@ static void ggml_compute_forward_rope_f16(
|
||||||
const int ith = params->ith;
|
const int ith = params->ith;
|
||||||
const int nth = params->nth;
|
const int nth = params->nth;
|
||||||
|
|
||||||
const int nr = ggml_nrows(src0);
|
const int nr = ggml_nrows(dst);
|
||||||
const int nc = src0->ne[0];
|
|
||||||
|
|
||||||
GGML_ASSERT(n_dims <= nc);
|
GGML_ASSERT(n_dims <= ne0);
|
||||||
GGML_ASSERT(n_dims % 2 == 0);
|
GGML_ASSERT(n_dims % 2 == 0);
|
||||||
|
|
||||||
// rows per thread
|
// rows per thread
|
||||||
|
@ -10883,21 +11100,21 @@ static void ggml_compute_forward_rope_f16(
|
||||||
|
|
||||||
for (int64_t i3 = 0; i3 < ne3; i3++) {
|
for (int64_t i3 = 0; i3 < ne3; i3++) {
|
||||||
for (int64_t i2 = ((mode & 1) == 0 ? 0 : n_past); i2 < ne2; i2++) {
|
for (int64_t i2 = ((mode & 1) == 0 ? 0 : n_past); i2 < ne2; i2++) {
|
||||||
const int p = ((mode & 1) == 0 ? n_past + i2 : i2);
|
const int64_t p = ((mode & 1) == 0 ? n_past + i2 : i2);
|
||||||
for (int64_t i1 = 0; i1 < ne1; i1++) {
|
for (int64_t i1 = 0; i1 < ne1; i1++) {
|
||||||
if (ir++ < ir0) continue;
|
if (ir++ < ir0) continue;
|
||||||
if (ir > ir1) break;
|
if (ir > ir1) break;
|
||||||
|
|
||||||
float theta = (float)p;
|
float theta = (float)p;
|
||||||
|
|
||||||
for (int i0 = 0; i0 < n_dims; i0 += 2) {
|
if (!is_neox) {
|
||||||
|
for (int64_t i0 = 0; i0 < ne0; i0 += 2) {
|
||||||
const float cos_theta = cosf(theta);
|
const float cos_theta = cosf(theta);
|
||||||
const float sin_theta = sinf(theta);
|
const float sin_theta = sinf(theta);
|
||||||
|
|
||||||
theta *= theta_scale;
|
theta *= theta_scale;
|
||||||
|
|
||||||
if (!is_neox) {
|
const ggml_fp16_t * const src = (ggml_fp16_t *)((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00);
|
||||||
const ggml_fp16_t * const src = (ggml_fp16_t *)((char *) src0->data + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
|
||||||
ggml_fp16_t * dst_data = (ggml_fp16_t *)((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
ggml_fp16_t * dst_data = (ggml_fp16_t *)((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
||||||
|
|
||||||
const float x0 = GGML_FP16_TO_FP32(src[0]);
|
const float x0 = GGML_FP16_TO_FP32(src[0]);
|
||||||
|
@ -10905,9 +11122,21 @@ static void ggml_compute_forward_rope_f16(
|
||||||
|
|
||||||
dst_data[0] = GGML_FP32_TO_FP16(x0*cos_theta - x1*sin_theta);
|
dst_data[0] = GGML_FP32_TO_FP16(x0*cos_theta - x1*sin_theta);
|
||||||
dst_data[1] = GGML_FP32_TO_FP16(x0*sin_theta + x1*cos_theta);
|
dst_data[1] = GGML_FP32_TO_FP16(x0*sin_theta + x1*cos_theta);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const ggml_fp16_t * const src = (ggml_fp16_t *)((char *) src0->data + i3*nb3 + i2*nb2 + i1*nb1 + (i0/2)*nb0);
|
// TODO: this is probably wrong, but I can't figure it out ..
|
||||||
ggml_fp16_t * dst_data = (ggml_fp16_t *)((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 + (i0/2)*nb0);
|
// ref: https://github.com/huggingface/transformers/blob/main/src/transformers/models/gpt_neox/modeling_gpt_neox.py#LL251C1-L294C28
|
||||||
|
for (int64_t ib = 0; ib < ne0/n_dims; ++ib) {
|
||||||
|
for (int64_t ic = 0; ic < n_dims; ic += 2) {
|
||||||
|
const float cos_theta = cosf(theta);
|
||||||
|
const float sin_theta = sinf(theta);
|
||||||
|
|
||||||
|
theta *= theta_scale;
|
||||||
|
|
||||||
|
const int64_t i0 = ib*n_dims + ic/2;
|
||||||
|
|
||||||
|
const ggml_fp16_t * const src = (ggml_fp16_t *)((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00);
|
||||||
|
ggml_fp16_t * dst_data = (ggml_fp16_t *)((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
||||||
|
|
||||||
const float x0 = GGML_FP16_TO_FP32(src[0]);
|
const float x0 = GGML_FP16_TO_FP32(src[0]);
|
||||||
const float x1 = GGML_FP16_TO_FP32(src[n_dims/2]);
|
const float x1 = GGML_FP16_TO_FP32(src[n_dims/2]);
|
||||||
|
@ -10919,6 +11148,7 @@ static void ggml_compute_forward_rope_f16(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ggml_compute_forward_rope(
|
static void ggml_compute_forward_rope(
|
||||||
|
@ -10964,15 +11194,23 @@ static void ggml_compute_forward_rope_back_f32(
|
||||||
const int n_dims = ((int32_t *) src1->data)[1];
|
const int n_dims = ((int32_t *) src1->data)[1];
|
||||||
const int mode = ((int32_t *) src1->data)[2];
|
const int mode = ((int32_t *) src1->data)[2];
|
||||||
|
|
||||||
//const int64_t ne0 = src0->ne[0];
|
assert(n_past >= 0);
|
||||||
const int64_t ne1 = src0->ne[1];
|
|
||||||
const int64_t ne2 = src0->ne[2];
|
const size_t nb00 = src0->nb[0];
|
||||||
const int64_t ne3 = src0->ne[3];
|
const size_t nb01 = src0->nb[1];
|
||||||
|
const size_t nb02 = src0->nb[2];
|
||||||
|
const size_t nb03 = src0->nb[3];
|
||||||
|
|
||||||
|
const int64_t ne0 = dst->ne[0];
|
||||||
|
const int64_t ne1 = dst->ne[1];
|
||||||
|
const int64_t ne2 = dst->ne[2];
|
||||||
|
const int64_t ne3 = dst->ne[3];
|
||||||
|
|
||||||
|
const size_t nb0 = dst->nb[0];
|
||||||
|
const size_t nb1 = dst->nb[1];
|
||||||
|
const size_t nb2 = dst->nb[2];
|
||||||
|
const size_t nb3 = dst->nb[3];
|
||||||
|
|
||||||
const int nb0 = src0->nb[0];
|
|
||||||
const int nb1 = src0->nb[1];
|
|
||||||
const int nb2 = src0->nb[2];
|
|
||||||
const int nb3 = src0->nb[3];
|
|
||||||
|
|
||||||
//printf("ne0: %d, ne1: %d, ne2: %d, ne3: %d\n", ne0, ne1, ne2, ne3);
|
//printf("ne0: %d, ne1: %d, ne2: %d, ne3: %d\n", ne0, ne1, ne2, ne3);
|
||||||
//printf("n_past = %d, ne2 = %d\n", n_past, ne2);
|
//printf("n_past = %d, ne2 = %d\n", n_past, ne2);
|
||||||
|
@ -10982,7 +11220,7 @@ static void ggml_compute_forward_rope_back_f32(
|
||||||
const int ith = params->ith;
|
const int ith = params->ith;
|
||||||
const int nth = params->nth;
|
const int nth = params->nth;
|
||||||
|
|
||||||
const int nr = ggml_nrows(src0);
|
const int nr = ggml_nrows(dst);
|
||||||
|
|
||||||
// rows per thread
|
// rows per thread
|
||||||
const int dr = (nr + nth - 1)/nth;
|
const int dr = (nr + nth - 1)/nth;
|
||||||
|
@ -11000,21 +11238,21 @@ static void ggml_compute_forward_rope_back_f32(
|
||||||
|
|
||||||
for (int64_t i3 = 0; i3 < ne3; i3++) {
|
for (int64_t i3 = 0; i3 < ne3; i3++) {
|
||||||
for (int64_t i2 = ((mode & 1) == 0 ? 0 : n_past); i2 < ne2; i2++) {
|
for (int64_t i2 = ((mode & 1) == 0 ? 0 : n_past); i2 < ne2; i2++) {
|
||||||
const int p = ((mode & 1) == 0 ? n_past + i2 : i2);
|
const int64_t p = ((mode & 1) == 0 ? n_past + i2 : i2);
|
||||||
for (int64_t i1 = 0; i1 < ne1; i1++) {
|
for (int64_t i1 = 0; i1 < ne1; i1++) {
|
||||||
if (ir++ < ir0) continue;
|
if (ir++ < ir0) continue;
|
||||||
if (ir > ir1) break;
|
if (ir > ir1) break;
|
||||||
|
|
||||||
float theta = (float)p;
|
float theta = (float)p;
|
||||||
|
|
||||||
for (int i0 = 0; i0 < n_dims; i0 += 2) {
|
if (!is_neox) {
|
||||||
|
for (int64_t i0 = 0; i0 < ne0; i0 += 2) {
|
||||||
const float cos_theta = cosf(theta);
|
const float cos_theta = cosf(theta);
|
||||||
const float sin_theta = sinf(theta);
|
const float sin_theta = sinf(theta);
|
||||||
|
|
||||||
theta *= theta_scale;
|
theta *= theta_scale;
|
||||||
|
|
||||||
if (!is_neox) {
|
const float * const dy = (float *)((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00);
|
||||||
const float * const dy = (float *)((char *) src0->data + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
|
||||||
float * dx = (float *)((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
float * dx = (float *)((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
||||||
|
|
||||||
const float dy0 = dy[0];
|
const float dy0 = dy[0];
|
||||||
|
@ -11022,9 +11260,19 @@ static void ggml_compute_forward_rope_back_f32(
|
||||||
|
|
||||||
dx[0] = dy0*cos_theta + dy1*sin_theta;
|
dx[0] = dy0*cos_theta + dy1*sin_theta;
|
||||||
dx[1] = - dy0*sin_theta + dy1*cos_theta;
|
dx[1] = - dy0*sin_theta + dy1*cos_theta;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const float * const dy = (float *)((char *) src0->data + i3*nb3 + i2*nb2 + i1*nb1 + (i0/2)*nb0);
|
for (int64_t ib = 0; ib < ne0/n_dims; ++ib) {
|
||||||
float * dx = (float *)((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 + (i0/2)*nb0);
|
for (int64_t ic = 0; ic < n_dims; ic += 2) {
|
||||||
|
const float cos_theta = cosf(theta);
|
||||||
|
const float sin_theta = sinf(theta);
|
||||||
|
|
||||||
|
theta *= theta_scale;
|
||||||
|
|
||||||
|
const int64_t i0 = ib*n_dims + ic/2;
|
||||||
|
|
||||||
|
const float * const dy = (float *)((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00);
|
||||||
|
float * dx = (float *)((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
||||||
|
|
||||||
const float dy0 = dy[0];
|
const float dy0 = dy[0];
|
||||||
const float dy1 = dy[n_dims/2];
|
const float dy1 = dy[n_dims/2];
|
||||||
|
@ -11036,6 +11284,7 @@ static void ggml_compute_forward_rope_back_f32(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ggml_compute_forward_rope_back_f16(
|
static void ggml_compute_forward_rope_back_f16(
|
||||||
|
@ -11058,15 +11307,23 @@ static void ggml_compute_forward_rope_back_f16(
|
||||||
const int n_dims = ((int32_t *) src1->data)[1];
|
const int n_dims = ((int32_t *) src1->data)[1];
|
||||||
const int mode = ((int32_t *) src1->data)[2];
|
const int mode = ((int32_t *) src1->data)[2];
|
||||||
|
|
||||||
//const int64_t ne0 = src0->ne[0];
|
assert(n_past >= 0);
|
||||||
const int64_t ne1 = src0->ne[1];
|
|
||||||
const int64_t ne2 = src0->ne[2];
|
const size_t nb00 = src0->nb[0];
|
||||||
const int64_t ne3 = src0->ne[3];
|
const size_t nb01 = src0->nb[1];
|
||||||
|
const size_t nb02 = src0->nb[2];
|
||||||
|
const size_t nb03 = src0->nb[3];
|
||||||
|
|
||||||
|
const int64_t ne0 = dst->ne[0];
|
||||||
|
const int64_t ne1 = dst->ne[1];
|
||||||
|
const int64_t ne2 = dst->ne[2];
|
||||||
|
const int64_t ne3 = dst->ne[3];
|
||||||
|
|
||||||
|
const size_t nb0 = dst->nb[0];
|
||||||
|
const size_t nb1 = dst->nb[1];
|
||||||
|
const size_t nb2 = dst->nb[2];
|
||||||
|
const size_t nb3 = dst->nb[3];
|
||||||
|
|
||||||
const int nb0 = src0->nb[0];
|
|
||||||
const int nb1 = src0->nb[1];
|
|
||||||
const int nb2 = src0->nb[2];
|
|
||||||
const int nb3 = src0->nb[3];
|
|
||||||
|
|
||||||
//printf("ne0: %d, ne1: %d, ne2: %d, ne3: %d\n", ne0, ne1, ne2, ne3);
|
//printf("ne0: %d, ne1: %d, ne2: %d, ne3: %d\n", ne0, ne1, ne2, ne3);
|
||||||
//printf("n_past = %d, ne2 = %d\n", n_past, ne2);
|
//printf("n_past = %d, ne2 = %d\n", n_past, ne2);
|
||||||
|
@ -11076,7 +11333,7 @@ static void ggml_compute_forward_rope_back_f16(
|
||||||
const int ith = params->ith;
|
const int ith = params->ith;
|
||||||
const int nth = params->nth;
|
const int nth = params->nth;
|
||||||
|
|
||||||
const int nr = ggml_nrows(src0);
|
const int nr = ggml_nrows(dst);
|
||||||
|
|
||||||
// rows per thread
|
// rows per thread
|
||||||
const int dr = (nr + nth - 1)/nth;
|
const int dr = (nr + nth - 1)/nth;
|
||||||
|
@ -11094,21 +11351,21 @@ static void ggml_compute_forward_rope_back_f16(
|
||||||
|
|
||||||
for (int64_t i3 = 0; i3 < ne3; i3++) {
|
for (int64_t i3 = 0; i3 < ne3; i3++) {
|
||||||
for (int64_t i2 = ((mode & 1) == 0 ? 0 : n_past); i2 < ne2; i2++) {
|
for (int64_t i2 = ((mode & 1) == 0 ? 0 : n_past); i2 < ne2; i2++) {
|
||||||
const int p = ((mode & 1) == 0 ? n_past + i2 : i2);
|
const int64_t p = ((mode & 1) == 0 ? n_past + i2 : i2);
|
||||||
for (int64_t i1 = 0; i1 < ne1; i1++) {
|
for (int64_t i1 = 0; i1 < ne1; i1++) {
|
||||||
if (ir++ < ir0) continue;
|
if (ir++ < ir0) continue;
|
||||||
if (ir > ir1) break;
|
if (ir > ir1) break;
|
||||||
|
|
||||||
float theta = (float)p;
|
float theta = (float)p;
|
||||||
|
|
||||||
for (int i0 = 0; i0 < n_dims; i0 += 2) {
|
if (!is_neox) {
|
||||||
|
for (int64_t i0 = 0; i0 < ne0; i0 += 2) {
|
||||||
const float cos_theta = cosf(theta);
|
const float cos_theta = cosf(theta);
|
||||||
const float sin_theta = sinf(theta);
|
const float sin_theta = sinf(theta);
|
||||||
|
|
||||||
theta *= theta_scale;
|
theta *= theta_scale;
|
||||||
|
|
||||||
if (!is_neox) {
|
const ggml_fp16_t * const dy = (ggml_fp16_t *)((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00);
|
||||||
const ggml_fp16_t * const dy = (ggml_fp16_t *)((char *) src0->data + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
|
||||||
ggml_fp16_t * dx = (ggml_fp16_t *)((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
ggml_fp16_t * dx = (ggml_fp16_t *)((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
||||||
|
|
||||||
const float dy0 = GGML_FP16_TO_FP32(dy[0]);
|
const float dy0 = GGML_FP16_TO_FP32(dy[0]);
|
||||||
|
@ -11116,9 +11373,19 @@ static void ggml_compute_forward_rope_back_f16(
|
||||||
|
|
||||||
dx[0] = GGML_FP32_TO_FP16( dy0*cos_theta + dy1*sin_theta);
|
dx[0] = GGML_FP32_TO_FP16( dy0*cos_theta + dy1*sin_theta);
|
||||||
dx[1] = GGML_FP32_TO_FP16(-dy0*sin_theta + dy1*cos_theta);
|
dx[1] = GGML_FP32_TO_FP16(-dy0*sin_theta + dy1*cos_theta);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const ggml_fp16_t * const dy = (ggml_fp16_t *)((char *) src0->data + i3*nb3 + i2*nb2 + i1*nb1 + (i0/2)*nb0);
|
for (int64_t ib = 0; ib < ne0/n_dims; ++ib) {
|
||||||
ggml_fp16_t * dx = (ggml_fp16_t *)((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 + (i0/2)*nb0);
|
for (int64_t ic = 0; ic < n_dims; ic += 2) {
|
||||||
|
const float cos_theta = cosf(theta);
|
||||||
|
const float sin_theta = sinf(theta);
|
||||||
|
|
||||||
|
theta *= theta_scale;
|
||||||
|
|
||||||
|
const int64_t i0 = ib*n_dims + ic/2;
|
||||||
|
|
||||||
|
const ggml_fp16_t * const dy = (ggml_fp16_t *)((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00);
|
||||||
|
ggml_fp16_t * dx = (ggml_fp16_t *)((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 + i0*nb0);
|
||||||
|
|
||||||
const float dy0 = GGML_FP16_TO_FP32(dy[0]);
|
const float dy0 = GGML_FP16_TO_FP32(dy[0]);
|
||||||
const float dy1 = GGML_FP16_TO_FP32(dy[n_dims/2]);
|
const float dy1 = GGML_FP16_TO_FP32(dy[n_dims/2]);
|
||||||
|
@ -11130,6 +11397,7 @@ static void ggml_compute_forward_rope_back_f16(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ggml_compute_forward_rope_back(
|
static void ggml_compute_forward_rope_back(
|
||||||
|
|
3
ggml.h
3
ggml.h
|
@ -190,6 +190,7 @@
|
||||||
#define GGML_FILE_MAGIC 0x67676d6c // "ggml"
|
#define GGML_FILE_MAGIC 0x67676d6c // "ggml"
|
||||||
#define GGML_FILE_VERSION 1
|
#define GGML_FILE_VERSION 1
|
||||||
|
|
||||||
|
#define GGML_QNT_VERSION 1 // bump this on quantization format changes
|
||||||
#define GGML_QNT_VERSION_FACTOR 1000 // do not change this
|
#define GGML_QNT_VERSION_FACTOR 1000 // do not change this
|
||||||
|
|
||||||
#define GGML_MAX_DIMS 4
|
#define GGML_MAX_DIMS 4
|
||||||
|
@ -374,7 +375,7 @@ extern "C" {
|
||||||
|
|
||||||
char name[32];
|
char name[32];
|
||||||
|
|
||||||
char padding[9]; // TODO: remove and add padding to name?
|
char padding[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
// computation graph
|
// computation graph
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue