mirror of
https://github.com/ggerganov/llama.cpp.git
synced 2026-02-26 14:23:22 +02:00
Compare commits
6 Commits
master-684
...
master-266
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2663d2c678 | ||
|
|
a0caa34b16 | ||
|
|
461ba9e66e | ||
|
|
c3ac702e5e | ||
|
|
9d634ef452 | ||
|
|
d9a239c410 |
@@ -42,6 +42,7 @@ New features will probably be added mostly through community contributions.
|
||||
- [X] [Chinese LLaMA / Alpaca](https://github.com/ymcui/Chinese-LLaMA-Alpaca)
|
||||
- [X] [Vigogne (French)](https://github.com/bofenghuang/vigogne)
|
||||
- [X] [Vicuna](https://github.com/ggerganov/llama.cpp/discussions/643#discussioncomment-5533894)
|
||||
- [X] [Koala](https://bair.berkeley.edu/blog/2023/04/03/koala/)
|
||||
|
||||
**Bindings:**
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// Defines sigaction on msys:
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include "llama.h"
|
||||
|
||||
|
||||
361
ggml.c
361
ggml.c
@@ -1,4 +1,4 @@
|
||||
// Defines CLOCK_MONOTONIC and asprintf on Linux
|
||||
// Defines CLOCK_MONOTONIC on Linux
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "ggml.h"
|
||||
@@ -26,14 +26,9 @@
|
||||
#define static_assert(cond, msg) struct global_scope_noop_trick
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER || defined(__MINGW32__)
|
||||
#if defined(_WIN32)
|
||||
|
||||
#if !defined(__MINGW32__)
|
||||
#include <Windows.h>
|
||||
#else
|
||||
// ref: https://github.com/ggerganov/whisper.cpp/issues/168
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
typedef volatile LONG atomic_int;
|
||||
typedef atomic_int atomic_bool;
|
||||
@@ -55,6 +50,7 @@ typedef HANDLE pthread_t;
|
||||
|
||||
typedef DWORD thread_ret_t;
|
||||
static int pthread_create(pthread_t* out, void* unused, thread_ret_t(*func)(void*), void* arg) {
|
||||
(void) unused;
|
||||
HANDLE handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) func, arg, 0, NULL);
|
||||
if (handle == NULL)
|
||||
{
|
||||
@@ -66,6 +62,7 @@ static int pthread_create(pthread_t* out, void* unused, thread_ret_t(*func)(void
|
||||
}
|
||||
|
||||
static int pthread_join(pthread_t thread, void* unused) {
|
||||
(void) unused;
|
||||
return (int) WaitForSingleObject(thread, INFINITE);
|
||||
}
|
||||
|
||||
@@ -1949,7 +1946,7 @@ static void ggml_vec_dot_q4_0(const int n, float * restrict s, const void * rest
|
||||
// Initialize accumulator with zeros
|
||||
__m256 acc = _mm256_setzero_ps();
|
||||
|
||||
/* Prepare the constants we will need during execution */
|
||||
/* Prepare the constants we will need during execution */
|
||||
const __m256i lowMask = _mm256_set1_epi8( 0xF );
|
||||
const __m256i offset_8 = _mm256_set1_epi16( 8 );
|
||||
|
||||
@@ -1959,61 +1956,59 @@ static void ggml_vec_dot_q4_0(const int n, float * restrict s, const void * rest
|
||||
|
||||
// Main loop
|
||||
for (int i = 0; i < nb; i+=UNROLL_COUNT) {
|
||||
|
||||
// This loop will be unrolled by the compiler
|
||||
// This loop will be unrolled by the compiler
|
||||
for (int u=0;u<UNROLL_COUNT;u++) {
|
||||
/* Compute combined scale for the block */
|
||||
const __m256 scale = _mm256_mul_ps(
|
||||
_mm256_broadcast_ss( &x[i+u].d ),
|
||||
_mm256_broadcast_ss( &y[i+u].d ) );
|
||||
/* Compute combined scale for the block */
|
||||
const __m256 scale = _mm256_mul_ps(
|
||||
_mm256_broadcast_ss( &x[i+u].d ),
|
||||
_mm256_broadcast_ss( &y[i+u].d ) );
|
||||
|
||||
/* get input from x
|
||||
Input: 32 Nibbles (16 bytes) at *x[i+u]
|
||||
Output: 2 vectors with 16 values of type int16_t (x_high_q, x_low_q) */
|
||||
|
||||
/* Load 16 bytes from memory */
|
||||
const __m128i tmp_x = _mm_loadu_si128( ( const __m128i* ) x[i+u].qs);
|
||||
/* Expand bytes into uint16_t values */
|
||||
const __m256i bytes_x = _mm256_cvtepu8_epi16(tmp_x);
|
||||
/* get input from x
|
||||
Input: 32 Nibbles (16 bytes) at *x[i+u]
|
||||
Output: 2 vectors with 16 values of type int16_t (x_high_q, x_low_q) */
|
||||
|
||||
/* Load 16 bytes from memory */
|
||||
const __m128i tmp_x = _mm_loadu_si128( ( const __m128i* ) x[i+u].qs);
|
||||
/* Expand bytes into uint16_t values */
|
||||
const __m256i bytes_x = _mm256_cvtepu8_epi16(tmp_x);
|
||||
/* Unpack values into individual bytes */
|
||||
__m256i x_low_q = _mm256_and_si256( lowMask, bytes_x );
|
||||
const __m256i pre_shift_x_high_q = _mm256_andnot_si256( lowMask, bytes_x );
|
||||
__m256i x_high_q = _mm256_srli_epi16( pre_shift_x_high_q, 4 );
|
||||
__m256i x_high_q = _mm256_srli_epi16( pre_shift_x_high_q, 4 );
|
||||
/* Now we have two vectors with bytes in [ 0 .. 15 ] interval. Offset them into [ -8 .. +7 ] interval. */
|
||||
x_high_q = _mm256_sub_epi16( x_high_q, offset_8 );
|
||||
x_low_q = _mm256_sub_epi16( x_low_q, offset_8 );
|
||||
x_high_q = _mm256_sub_epi16( x_high_q, offset_8 );
|
||||
x_low_q = _mm256_sub_epi16( x_low_q, offset_8 );
|
||||
|
||||
/* get input from y
|
||||
Input: 32 Nibbles (16 bytes) at *y[i+u]
|
||||
Output: 2 vectors with 16 values of type int16_t (y_high_q, y_low_q) */
|
||||
/* get input from y
|
||||
Input: 32 Nibbles (16 bytes) at *y[i+u]
|
||||
Output: 2 vectors with 16 values of type int16_t (y_high_q, y_low_q) */
|
||||
|
||||
/* Load 16 bytes from memory */
|
||||
const __m128i tmp_y = _mm_loadu_si128( (const __m128i* ) y[i+u].qs);
|
||||
/* Expand bytes into uint16_t values */
|
||||
const __m256i bytes_y = _mm256_cvtepu8_epi16(tmp_y);
|
||||
/* Load 16 bytes from memory */
|
||||
const __m128i tmp_y = _mm_loadu_si128( (const __m128i* ) y[i+u].qs);
|
||||
/* Expand bytes into uint16_t values */
|
||||
const __m256i bytes_y = _mm256_cvtepu8_epi16(tmp_y);
|
||||
/* Unpack values into individual bytes */
|
||||
const __m256i pre_shift_y_high_q = _mm256_andnot_si256( lowMask, bytes_y );
|
||||
__m256i y_high_q = _mm256_srli_epi16( pre_shift_y_high_q, 4 );
|
||||
__m256i y_low_q = _mm256_and_si256( lowMask, bytes_y );
|
||||
const __m256i pre_shift_y_high_q = _mm256_andnot_si256( lowMask, bytes_y );
|
||||
__m256i y_high_q = _mm256_srli_epi16( pre_shift_y_high_q, 4 );
|
||||
__m256i y_low_q = _mm256_and_si256( lowMask, bytes_y );
|
||||
/* Now we have two vectors with bytes in [ 0 .. 15 ] interval. Offset them into [ -8 .. +7 ] interval. */
|
||||
y_high_q = _mm256_sub_epi16( y_high_q, offset_8 );
|
||||
y_low_q = _mm256_sub_epi16( y_low_q, offset_8 );
|
||||
y_high_q = _mm256_sub_epi16( y_high_q, offset_8 );
|
||||
y_low_q = _mm256_sub_epi16( y_low_q, offset_8 );
|
||||
|
||||
/* Compute products of int16_t integers, add pairwise, store as int32_t */
|
||||
__m256i xy_high_q = _mm256_madd_epi16( x_high_q, y_high_q );
|
||||
__m256i xy_low_q = _mm256_madd_epi16( x_low_q, y_low_q );
|
||||
/* Compute products of int16_t integers, add pairwise, store as int32_t */
|
||||
__m256i xy_high_q = _mm256_madd_epi16( x_high_q, y_high_q );
|
||||
__m256i xy_low_q = _mm256_madd_epi16( x_low_q, y_low_q );
|
||||
|
||||
/* Accumulate the products of int32_t integers -> we now have a vector of 8 int_32t */
|
||||
__m256i xy_q = _mm256_add_epi32( xy_high_q, xy_low_q );
|
||||
/* Accumulate the products of int32_t integers -> we now have a vector of 8 int_32t */
|
||||
__m256i xy_q = _mm256_add_epi32( xy_high_q, xy_low_q );
|
||||
|
||||
/* Convert to vectore of 8 int32_t to 8 floats */
|
||||
__m256 q = _mm256_cvtepi32_ps( xy_q );
|
||||
/* Convert to vectore of 8 int32_t to 8 floats */
|
||||
__m256 q = _mm256_cvtepi32_ps( xy_q );
|
||||
|
||||
/* Multiply q with scale and accumulate */
|
||||
acc = _mm256_fmadd_ps( scale, q, acc );
|
||||
/* Multiply q with scale and accumulate */
|
||||
acc = _mm256_fmadd_ps( scale, q, acc );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Return horizontal sum of the acc vector
|
||||
__m128 res = _mm256_extractf128_ps( acc, 1 );
|
||||
@@ -2074,18 +2069,18 @@ static void ggml_vec_dot_q4_0(const int n, float * restrict s, const void * rest
|
||||
float sum1 = 0.0f;
|
||||
|
||||
for (int i = 0; i < nb; i += 2) {
|
||||
const block_q4_0 * restrict x0 = &px[i + 0];
|
||||
const block_q4_0 * restrict y0 = &py[i + 0];
|
||||
const block_q4_0 * restrict x1 = &px[i + 1];
|
||||
const block_q4_0 * restrict y1 = &py[i + 1];
|
||||
const block_q4_0 * restrict x0 = &x[i + 0];
|
||||
const block_q4_0 * restrict y0 = &y[i + 0];
|
||||
const block_q4_0 * restrict x1 = &x[i + 1];
|
||||
const block_q4_0 * restrict y1 = &y[i + 1];
|
||||
|
||||
const v128_t m4b = wasm_u8x16_splat(0xf);
|
||||
const v128_t s8b = wasm_i8x16_splat(0x8);
|
||||
|
||||
const v128_t v0_0 = wasm_v128_load(x0.qs);
|
||||
const v128_t v0_1 = wasm_v128_load(y0.qs);
|
||||
const v128_t v1_0 = wasm_v128_load(x1.qs);
|
||||
const v128_t v1_1 = wasm_v128_load(y1.qs);
|
||||
const v128_t v0_0 = wasm_v128_load(x0->qs);
|
||||
const v128_t v0_1 = wasm_v128_load(y0->qs);
|
||||
const v128_t v1_0 = wasm_v128_load(x1->qs);
|
||||
const v128_t v1_1 = wasm_v128_load(y1->qs);
|
||||
|
||||
// 4-bit -> 8-bit
|
||||
const v128_t v0_0l = wasm_v128_and(v0_0, m4b);
|
||||
@@ -2616,6 +2611,7 @@ static const char * GGML_OP_LABEL[GGML_OP_COUNT] = {
|
||||
|
||||
"SCALE",
|
||||
"CPY",
|
||||
"CONT",
|
||||
"RESHAPE",
|
||||
"VIEW",
|
||||
"PERMUTE",
|
||||
@@ -2631,7 +2627,7 @@ static const char * GGML_OP_LABEL[GGML_OP_COUNT] = {
|
||||
"FLASH_FF",
|
||||
};
|
||||
|
||||
static_assert(GGML_OP_COUNT == 35, "GGML_OP_COUNT != 35");
|
||||
static_assert(GGML_OP_COUNT == 36, "GGML_OP_COUNT != 36");
|
||||
|
||||
static const char * GGML_OP_SYMBOL[GGML_OP_COUNT] = {
|
||||
"none",
|
||||
@@ -2660,6 +2656,7 @@ static const char * GGML_OP_SYMBOL[GGML_OP_COUNT] = {
|
||||
|
||||
"x*v",
|
||||
"x-\\>y",
|
||||
"cont(x)",
|
||||
"reshape(x)",
|
||||
"view(x)",
|
||||
"permute(x)",
|
||||
@@ -2675,7 +2672,7 @@ static const char * GGML_OP_SYMBOL[GGML_OP_COUNT] = {
|
||||
"flash_ff(x)",
|
||||
};
|
||||
|
||||
static_assert(GGML_OP_COUNT == 35, "GGML_OP_COUNT != 35");
|
||||
static_assert(GGML_OP_COUNT == 36, "GGML_OP_COUNT != 36");
|
||||
|
||||
static_assert(sizeof(struct ggml_object)%GGML_MEM_ALIGN == 0, "ggml_object size must be a multiple of GGML_MEM_ALIGN");
|
||||
static_assert(sizeof(struct ggml_tensor)%GGML_MEM_ALIGN == 0, "ggml_tensor size must be a multiple of GGML_MEM_ALIGN");
|
||||
@@ -4308,6 +4305,41 @@ struct ggml_tensor * ggml_cpy_inplace(
|
||||
return ggml_cpy_impl(ctx, a, b, true);
|
||||
}
|
||||
|
||||
// ggml_cont
|
||||
|
||||
struct ggml_tensor * ggml_cont_impl(
|
||||
struct ggml_context * ctx,
|
||||
struct ggml_tensor * a,
|
||||
bool inplace) {
|
||||
bool is_node = false;
|
||||
|
||||
if (!inplace && a->grad) {
|
||||
GGML_ASSERT(false); // TODO: implement backward
|
||||
is_node = true;
|
||||
}
|
||||
|
||||
struct ggml_tensor * result = inplace ? ggml_view_tensor(ctx, a) : ggml_dup_tensor(ctx, a);
|
||||
|
||||
result->op = GGML_OP_CONT;
|
||||
result->grad = is_node ? ggml_dup_tensor(ctx, result) : NULL;
|
||||
result->src0 = a;
|
||||
result->src1 = NULL;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct ggml_tensor * ggml_cont(
|
||||
struct ggml_context * ctx,
|
||||
struct ggml_tensor * a) {
|
||||
return ggml_cont_impl(ctx, a, false);
|
||||
}
|
||||
|
||||
struct ggml_tensor * ggml_cont_inplace(
|
||||
struct ggml_context * ctx,
|
||||
struct ggml_tensor * a) {
|
||||
return ggml_cont_impl(ctx, a, true);
|
||||
}
|
||||
|
||||
// ggml_reshape
|
||||
|
||||
struct ggml_tensor * ggml_reshape(
|
||||
@@ -4850,6 +4882,85 @@ static void ggml_compute_forward_dup_f16(
|
||||
|
||||
// TODO: add more special-case implementations for tensor shapes/strides that can benefit from memcpy
|
||||
|
||||
if (ggml_is_contiguous(dst)) {
|
||||
if (src0->nb[0] == sizeof(ggml_fp16_t)) {
|
||||
if (dst->type == GGML_TYPE_F16) {
|
||||
size_t id = 0;
|
||||
const size_t rs = ne00*nb00;
|
||||
|
||||
for (int i03 = 0; i03 < ne03; i03++) {
|
||||
for (int i02 = 0; i02 < ne02; i02++) {
|
||||
for (int i01 = 0; i01 < ne01; i01++) {
|
||||
const char * src0_ptr = (char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03;
|
||||
char * dst_ptr = (char *) dst->data + id*rs;
|
||||
|
||||
memcpy(dst_ptr, src0_ptr, rs);
|
||||
|
||||
id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (dst->type == GGML_TYPE_F32) {
|
||||
size_t id = 0;
|
||||
float * dst_ptr = (float *) dst->data;
|
||||
|
||||
for (int i03 = 0; i03 < ne03; i03++) {
|
||||
for (int i02 = 0; i02 < ne02; i02++) {
|
||||
for (int i01 = 0; i01 < ne01; i01++) {
|
||||
for (int i00 = 0; i00 < ne00; i00++) {
|
||||
const ggml_fp16_t * src0_ptr = (ggml_fp16_t *) ((char *) src0->data + i00*nb00 + i01*nb01 + i02*nb02 + i03*nb03);
|
||||
|
||||
dst_ptr[id] = GGML_FP16_TO_FP32(*src0_ptr);
|
||||
id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
GGML_ASSERT(false); // TODO: implement
|
||||
}
|
||||
} else {
|
||||
//printf("%s: this is not optimal - fix me\n", __func__);
|
||||
|
||||
if (dst->type == GGML_TYPE_F32) {
|
||||
size_t id = 0;
|
||||
float * dst_ptr = (float *) dst->data;
|
||||
|
||||
for (int i03 = 0; i03 < ne03; i03++) {
|
||||
for (int i02 = 0; i02 < ne02; i02++) {
|
||||
for (int i01 = 0; i01 < ne01; i01++) {
|
||||
for (int i00 = 0; i00 < ne00; i00++) {
|
||||
const ggml_fp16_t * src0_ptr = (ggml_fp16_t *) ((char *) src0->data + i00*nb00 + i01*nb01 + i02*nb02 + i03*nb03);
|
||||
|
||||
dst_ptr[id] = GGML_FP16_TO_FP32(*src0_ptr);
|
||||
id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (dst->type == GGML_TYPE_F16) {
|
||||
size_t id = 0;
|
||||
ggml_fp16_t * dst_ptr = (ggml_fp16_t *) dst->data;
|
||||
|
||||
for (int i03 = 0; i03 < ne03; i03++) {
|
||||
for (int i02 = 0; i02 < ne02; i02++) {
|
||||
for (int i01 = 0; i01 < ne01; i01++) {
|
||||
for (int i00 = 0; i00 < ne00; i00++) {
|
||||
const ggml_fp16_t * src0_ptr = (ggml_fp16_t *) ((char *) src0->data + i00*nb00 + i01*nb01 + i02*nb02 + i03*nb03);
|
||||
|
||||
dst_ptr[id] = *src0_ptr;
|
||||
id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
GGML_ASSERT(false); // TODO: implement
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// dst counters
|
||||
int64_t i10 = 0;
|
||||
int64_t i11 = 0;
|
||||
@@ -4944,6 +5055,105 @@ static void ggml_compute_forward_dup_f32(
|
||||
return;
|
||||
}
|
||||
|
||||
if (src0->type == dst->type &&
|
||||
src0->ne[0] == dst->ne[0] &&
|
||||
src0->nb[0] == GGML_TYPE_SIZE[src0->type] && dst->nb[0] == GGML_TYPE_SIZE[dst->type]) {
|
||||
// copy by rows
|
||||
const size_t rs = ne00*nb00;
|
||||
for (int64_t i03 = 0; i03 < ne03; i03++) {
|
||||
for (int64_t i02 = 0; i02 < ne02; i02++) {
|
||||
for (int64_t i01 = 0; i01 < ne01; i01++) {
|
||||
memcpy(
|
||||
((char *) dst->data + i01*nb1 + i02*nb2 + i03*nb3),
|
||||
((char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03),
|
||||
rs);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (ggml_is_contiguous(dst)) {
|
||||
// TODO: simplify
|
||||
if (src0->nb[0] == sizeof(float)) {
|
||||
if (dst->type == GGML_TYPE_F32) {
|
||||
size_t id = 0;
|
||||
const size_t rs = ne00*nb00;
|
||||
|
||||
for (int i03 = 0; i03 < ne03; i03++) {
|
||||
for (int i02 = 0; i02 < ne02; i02++) {
|
||||
for (int i01 = 0; i01 < ne01; i01++) {
|
||||
const char * src0_ptr = (char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03;
|
||||
char * dst_ptr = (char *) dst->data + id*rs;
|
||||
|
||||
memcpy(dst_ptr, src0_ptr, rs);
|
||||
|
||||
id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (dst->type == GGML_TYPE_F16) {
|
||||
size_t id = 0;
|
||||
ggml_fp16_t * dst_ptr = (ggml_fp16_t *) dst->data;
|
||||
|
||||
for (int i03 = 0; i03 < ne03; i03++) {
|
||||
for (int i02 = 0; i02 < ne02; i02++) {
|
||||
for (int i01 = 0; i01 < ne01; i01++) {
|
||||
for (int i00 = 0; i00 < ne00; i00++) {
|
||||
const float * src0_ptr = (float *) ((char *) src0->data + i00*nb00 + i01*nb01 + i02*nb02 + i03*nb03);
|
||||
|
||||
dst_ptr[id] = GGML_FP32_TO_FP16(*src0_ptr);
|
||||
id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
GGML_ASSERT(false); // TODO: implement
|
||||
}
|
||||
} else {
|
||||
//printf("%s: this is not optimal - fix me\n", __func__);
|
||||
|
||||
if (dst->type == GGML_TYPE_F32) {
|
||||
size_t id = 0;
|
||||
float * dst_ptr = (float *) dst->data;
|
||||
|
||||
for (int i03 = 0; i03 < ne03; i03++) {
|
||||
for (int i02 = 0; i02 < ne02; i02++) {
|
||||
for (int i01 = 0; i01 < ne01; i01++) {
|
||||
for (int i00 = 0; i00 < ne00; i00++) {
|
||||
const float * src0_ptr = (float *) ((char *) src0->data + i00*nb00 + i01*nb01 + i02*nb02 + i03*nb03);
|
||||
|
||||
dst_ptr[id] = *src0_ptr;
|
||||
id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (dst->type == GGML_TYPE_F16) {
|
||||
size_t id = 0;
|
||||
ggml_fp16_t * dst_ptr = (ggml_fp16_t *) dst->data;
|
||||
|
||||
for (int i03 = 0; i03 < ne03; i03++) {
|
||||
for (int i02 = 0; i02 < ne02; i02++) {
|
||||
for (int i01 = 0; i01 < ne01; i01++) {
|
||||
for (int i00 = 0; i00 < ne00; i00++) {
|
||||
const float * src0_ptr = (float *) ((char *) src0->data + i00*nb00 + i01*nb01 + i02*nb02 + i03*nb03);
|
||||
|
||||
dst_ptr[id] = GGML_FP32_TO_FP16(*src0_ptr);
|
||||
id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
GGML_ASSERT(false); // TODO: implement
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// dst counters
|
||||
int64_t i10 = 0;
|
||||
int64_t i11 = 0;
|
||||
@@ -5064,14 +5274,18 @@ static void ggml_compute_forward_add_f32(
|
||||
GGML_ASSERT(nb00 == sizeof(float));
|
||||
|
||||
if (nb10 == sizeof(float)) {
|
||||
const int j0 = (n/nth)*ith;
|
||||
const int j1 = ith == nth - 1 ? n : (n/nth)*(ith + 1);
|
||||
|
||||
for (int j = j0; j < j1; j++) {
|
||||
for (int j = ith; j < n; j += nth) {
|
||||
#ifdef GGML_USE_ACCELERATE
|
||||
vDSP_vadd(
|
||||
(float *) ((char *) src0->data + j*nb01), 1,
|
||||
(float *) ((char *) src1->data + j*nb11), 1,
|
||||
(float *) ((char *) dst->data + j*nb1), 1, nc);
|
||||
#else
|
||||
ggml_vec_add_f32(nc,
|
||||
(float *) ((char *) dst->data + j*nb1),
|
||||
(float *) ((char *) src0->data + j*nb01),
|
||||
(float *) ((char *) src1->data + j*nb11));
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
// src1 is not contiguous
|
||||
@@ -6819,6 +7033,15 @@ static void ggml_compute_forward_cpy(
|
||||
ggml_compute_forward_dup(params, src0, dst);
|
||||
}
|
||||
|
||||
// ggml_compute_forward_cont
|
||||
|
||||
static void ggml_compute_forward_cont(
|
||||
const struct ggml_compute_params * params,
|
||||
const struct ggml_tensor * src0,
|
||||
struct ggml_tensor * dst) {
|
||||
ggml_compute_forward_dup(params, src0, dst);
|
||||
}
|
||||
|
||||
// ggml_compute_forward_reshape
|
||||
|
||||
static void ggml_compute_forward_reshape(
|
||||
@@ -8649,6 +8872,10 @@ static void ggml_compute_forward(struct ggml_compute_params * params, struct ggm
|
||||
{
|
||||
ggml_compute_forward_cpy(params, tensor->src0, tensor);
|
||||
} break;
|
||||
case GGML_OP_CONT:
|
||||
{
|
||||
ggml_compute_forward_cont(params, tensor->src0, tensor);
|
||||
} break;
|
||||
case GGML_OP_RESHAPE:
|
||||
{
|
||||
ggml_compute_forward_reshape(params, tensor->src0, tensor);
|
||||
@@ -8893,8 +9120,9 @@ static void ggml_compute_backward(struct ggml_context * ctx, struct ggml_tensor
|
||||
src1->grad =
|
||||
ggml_add_impl(ctx,
|
||||
src1->grad,
|
||||
// TODO: fix transpose, the node will break the graph connections
|
||||
ggml_mul_mat(ctx, ggml_transpose(ctx, src0), tensor->grad),
|
||||
ggml_mul_mat(ctx,
|
||||
ggml_cont(ctx, ggml_transpose(ctx, src0)),
|
||||
tensor->grad),
|
||||
inplace);
|
||||
}
|
||||
} break;
|
||||
@@ -8906,6 +9134,10 @@ static void ggml_compute_backward(struct ggml_context * ctx, struct ggml_tensor
|
||||
{
|
||||
GGML_ASSERT(false); // TODO: not implemented
|
||||
} break;
|
||||
case GGML_OP_CONT:
|
||||
{
|
||||
GGML_ASSERT(false); // TODO: not implemented
|
||||
} break;
|
||||
case GGML_OP_RESHAPE:
|
||||
{
|
||||
GGML_ASSERT(false); // TODO: not implemented
|
||||
@@ -9360,6 +9592,7 @@ void ggml_graph_compute(struct ggml_context * ctx, struct ggml_cgraph * cgraph)
|
||||
node->n_tasks = n_threads;
|
||||
} break;
|
||||
case GGML_OP_CPY:
|
||||
case GGML_OP_CONT:
|
||||
case GGML_OP_RESHAPE:
|
||||
case GGML_OP_VIEW:
|
||||
case GGML_OP_PERMUTE:
|
||||
|
||||
6
ggml.h
6
ggml.h
@@ -236,6 +236,7 @@ enum ggml_op {
|
||||
|
||||
GGML_OP_SCALE,
|
||||
GGML_OP_CPY,
|
||||
GGML_OP_CONT,
|
||||
GGML_OP_RESHAPE,
|
||||
GGML_OP_VIEW,
|
||||
GGML_OP_PERMUTE,
|
||||
@@ -525,6 +526,11 @@ struct ggml_tensor * ggml_cpy(
|
||||
struct ggml_tensor * a,
|
||||
struct ggml_tensor * b);
|
||||
|
||||
// make contiguous
|
||||
struct ggml_tensor * ggml_cont(
|
||||
struct ggml_context * ctx,
|
||||
struct ggml_tensor * a);
|
||||
|
||||
// return view(a), b specifies the new shape
|
||||
// TODO: when we start computing gradient, make a copy instead of view
|
||||
struct ggml_tensor * ggml_reshape(
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// Defines fileno on msys:
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "llama_util.h"
|
||||
#include "llama.h"
|
||||
#include "llama_internal.h"
|
||||
|
||||
12
llama_util.h
12
llama_util.h
@@ -26,7 +26,9 @@
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOMINMAX
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#include <stdio.h> // for _fseeki64
|
||||
@@ -209,6 +211,7 @@ struct llama_mmap {
|
||||
throw format("MapViewOfFile failed: %s", llama_format_win_err(error).c_str());
|
||||
}
|
||||
|
||||
#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
|
||||
// Advise the kernel to preload the mapped memory
|
||||
WIN32_MEMORY_RANGE_ENTRY range;
|
||||
range.VirtualAddress = addr;
|
||||
@@ -217,6 +220,9 @@ struct llama_mmap {
|
||||
fprintf(stderr, "warning: PrefetchVirtualMemory failed: %s\n",
|
||||
llama_format_win_err(GetLastError()).c_str());
|
||||
}
|
||||
#else
|
||||
#pragma message("warning: You are building for pre-Windows 8; prefetch not supported")
|
||||
#endif // _WIN32_WINNT >= _WIN32_WINNT_WIN8
|
||||
}
|
||||
|
||||
~llama_mmap() {
|
||||
@@ -338,8 +344,8 @@ struct llama_mlock {
|
||||
// Hopefully a megabyte is enough overhead:
|
||||
size_t increment = size + 1048576;
|
||||
// The minimum must be <= the maximum, so we need to increase both:
|
||||
min_ws_size += size;
|
||||
max_ws_size += size;
|
||||
min_ws_size += increment;
|
||||
max_ws_size += increment;
|
||||
if (!SetProcessWorkingSetSize(GetCurrentProcess(), min_ws_size, max_ws_size)) {
|
||||
fprintf(stderr, "warning: SetProcessWorkingSetSize failed: %s\n",
|
||||
llama_format_win_err(GetLastError()).c_str());
|
||||
|
||||
Reference in New Issue
Block a user