4444#if defined(_WIN32)
4545
4646#include <windows.h>
47-
47+ #ifndef atomic_int
4848typedef volatile LONG atomic_int;
4949typedef atomic_int atomic_bool;
50+ #endif
5051
5152static void atomic_store(atomic_int* ptr, LONG val) {
5253 InterlockedExchange(ptr, val);
@@ -3761,9 +3762,6 @@ struct ggml_context_container {
37613762 struct ggml_context context;
37623763};
37633764
3764- //
3765- // ggml state
3766- //
37673765
37683766struct ggml_state {
37693767 struct ggml_context_container contexts[GGML_MAX_CONTEXTS];
@@ -9939,18 +9937,20 @@ static void ggml_compute_forward_rms_norm_f32(
99399937 GGML_ASSERT(ggml_are_same_shape(src0, dst));
99409938
99419939 if (params->type == GGML_TASK_INIT || params->type == GGML_TASK_FINALIZE) {
9940+ atomic_store(params->aic, 0);
9941+
99429942 return;
99439943 }
99449944
99459945 GGML_ASSERT(src0->nb[0] == sizeof(float));
99469946
9947- const int ith = params->ith;
9947+ const int ith = params->ith; UNUSED(ith);
99489948 const int nth = params->nth;
99499949
99509950 const int64_t ne00 = src0->ne[0];
99519951 const int64_t ne01 = src0->ne[1];
99529952 const int64_t ne02 = src0->ne[2];
9953- const int64_t ne03 = src0->ne[3];
9953+ const int64_t ne03 = src0->ne[3]; UNUSED(ne03);
99549954
99559955 const size_t nb01 = src0->nb[1];
99569956 const size_t nb02 = src0->nb[2];
@@ -9962,30 +9962,45 @@ static void ggml_compute_forward_rms_norm_f32(
99629962
99639963 const float eps = 1e-6f; // TODO: make this a parameter
99649964
9965- // TODO: optimize
9966- for (int64_t i03 = 0; i03 < ne03; i03++) {
9967- for (int64_t i02 = 0; i02 < ne02; i02++) {
9968- for (int64_t i01 = ith; i01 < ne01; i01 += nth) {
9969- const float * x = (float *) ((char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03);
9970-
9971- ggml_float sum = 0.0;
9972- for (int64_t i00 = 0; i00 < ne00; i00++) {
9973- sum += (ggml_float)(x[i00] * x[i00]);
9974- }
9965+ const int nr = ggml_nrows(src0);
9966+ const int dr = (nr + 8*nth - 1)/(8*nth);
99759967
9976- const float mean = sum/ne00;
9968+ while (true) {
9969+ const int ir0 = atomic_fetch_add(params->aic, dr);
99779970
9978- float * y = (float *) ((char *) dst->data + i01*nb1 + i02*nb2 + i03*nb3);
9971+ for (int ir = ir0; ir < ir0 + dr; ++ir) {
9972+ if (ir >= nr) {
9973+ break;
9974+ }
99799975
9980- memcpy(y, x, ne00 * sizeof(float));
9981- // for ( int i00 = 0; i00 < ne00; i00++) {
9982- // y[i00] = x[i00] ;
9983- // }
9976+ // src0 indices
9977+ const int i03 = ir/(ne02*ne01);
9978+ const int i02 = (ir - i03*ne02*ne01)/ne01 ;
9979+ const int i01 = (ir - i03*ne02*ne01 - i02*ne01);
99849980
9985- const float scale = 1.0f/sqrtf(mean + eps );
9981+ const float * x = ( float *) ((char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03 );
99869982
9987- ggml_vec_scale_f32(ne00, y, scale);
9983+ ggml_float sum = 0.0;
9984+ for (int64_t i00 = 0; i00 < ne00; i00++) {
9985+ sum += (ggml_float)(x[i00] * x[i00]);
99889986 }
9987+
9988+ float mean = sum/ne00;
9989+
9990+ float * y = (float *) ((char *) dst->data + i01*nb1 + i02*nb2 + i03*nb3);
9991+
9992+ memcpy(y, x, ne00 * sizeof(float));
9993+ // for (int i00 = 0; i00 < ne00; i00++) {
9994+ // y[i00] = x[i00];
9995+ // }
9996+
9997+ const float scale = 1.0f/sqrtf(mean + eps);
9998+
9999+ ggml_vec_scale_f32(ne00, y, scale);
10000+ }
10001+
10002+ if (ir0 + dr >= nr) {
10003+ break;
998910004 }
999010005 }
999110006}
@@ -10635,7 +10650,7 @@ static void ggml_compute_forward_mul_mat_q_f32(
1063510650 const int nb2 = dst->nb[2];
1063610651 const int nb3 = dst->nb[3];
1063710652
10638- const int ith = params->ith;
10653+ const int ith = params->ith; UNUSED(ith);
1063910654 const int nth = params->nth;
1064010655
1064110656 GGML_ASSERT(ne02 == ne12);
@@ -10737,50 +10752,57 @@ static void ggml_compute_forward_mul_mat_q_f32(
1073710752 }
1073810753 }
1073910754
10755+ atomic_store(params->aic, 0);
10756+
1074010757 return;
1074110758 }
1074210759
1074310760 if (params->type == GGML_TASK_FINALIZE) {
1074410761 return;
1074510762 }
1074610763
10764+ void * wdata = params->wdata;
10765+ const size_t row_size = ne00*GGML_TYPE_SIZE[vec_dot_type]/GGML_BLCK_SIZE[vec_dot_type];
10766+
1074710767 // parallelize by src0 rows using ggml_vec_dot_q
1074810768
10749- // total rows in src0
10750- const int nr = ne01*ne02*ne03;
10769+ const int nr = ggml_nrows(src0); // nr stands for number of rows
10770+ const int dr = (nr + 8*nth - 1)/(8*nth); // dr stands for delta rows
1075110771
10752- // rows per thread
10753- const int dr = (nr + nth - 1)/nth ;
10772+ while (true) {
10773+ const int ir0 = atomic_fetch_add(params->aic, dr) ;
1075410774
10755- // row range for this thread
10756- const int ir0 = dr*ith;
10757- const int ir1 = MIN(ir0 + dr, nr);
10775+ for (int ir = ir0; ir < ir0 + dr; ++ir) {
10776+ if (ir >= nr) {
10777+ break;
10778+ }
1075810779
10759- void * wdata = params->wdata;
10760- const size_t row_size = ne00*GGML_TYPE_SIZE[vec_dot_type]/GGML_BLCK_SIZE[vec_dot_type];
10780+ // src0 indices
10781+ const int i03 = ir/(ne02*ne01);
10782+ const int i02 = (ir - i03*ne02*ne01)/ne01;
10783+ const int i01 = (ir - i03*ne02*ne01 - i02*ne01);
1076110784
10762- for (int ir = ir0; ir < ir1; ++ir) {
10763- // src0 indices
10764- const int i03 = ir/(ne02*ne01);
10765- const int i02 = (ir - i03*ne02*ne01)/ne01;
10766- const int i01 = (ir - i03*ne02*ne01 - i02*ne01);
10785+ const int i13 = i03;
10786+ const int i12 = i02;
1076710787
10768- const int i13 = i03;
10769- const int i12 = i02;
10788+ const int i0 = i01;
10789+ const int i2 = i02;
10790+ const int i3 = i03;
1077010791
10771- const int i0 = i01;
10772- const int i2 = i02;
10773- const int i3 = i03;
10792+ void * src0_row = (void *) ((char *) src0->data + (i01*nb01 + i02*nb02 + i03*nb03));
10793+ char * src1_col = ((char *) wdata + ( (0 + i12*ne11 + i13*ne12*ne11)*row_size));
1077410794
10775- void * src0_row = (void *) ((char *) src0->data + (i01*nb01 + i02*nb02 + i03*nb03));
10776- char * src1_col = ((char *) wdata + ( (0 + i12*ne11 + i13*ne12*ne11)*row_size));
10795+ float * dst_col = (float *) ((char *) dst->data + (i0*nb0 + 0*nb1 + i2*nb2 + i3*nb3));
1077710796
10778- float * dst_col = (float *) ((char *) dst->data + (i0*nb0 + 0*nb1 + i2*nb2 + i3*nb3) );
10797+ assert(ne00 % 32 == 0 );
1077910798
10780- assert(ne00 % 32 == 0);
10799+ for (int64_t ic = 0; ic < ne11; ++ic) {
10800+ vec_dot_q(ne00, &dst_col[ic*ne0], src0_row, (void *) (src1_col + ic*row_size));
10801+ }
10802+ }
1078110803
10782- for (int64_t ic = 0; ic < ne11; ++ic ) {
10783- vec_dot_q(ne00, &dst_col[ic*ne0], src0_row, (void *) (src1_col + ic*row_size)) ;
10804+ if (ir0 + dr >= nr ) {
10805+ break ;
1078410806 }
1078510807 }
1078610808
@@ -15879,6 +15901,7 @@ struct ggml_compute_state_shared {
1587915901
1588015902 // synchronization primitives
1588115903 atomic_int n_ready;
15904+ atomic_int aic;
1588215905 atomic_bool has_work;
1588315906 atomic_bool stop; // stop all threads
1588415907};
@@ -15947,6 +15970,7 @@ void ggml_graph_compute(struct ggml_context * ctx, struct ggml_cgraph * cgraph)
1594715970 /*.spin =*/ GGML_LOCK_INITIALIZER,
1594815971 /*.n_threads =*/ n_threads,
1594915972 /*.n_ready =*/ 0,
15973+ /*.aic =*/ 0,
1595015974 /*.has_work =*/ false,
1595115975 /*.stop =*/ false,
1595215976 };
@@ -15967,6 +15991,7 @@ void ggml_graph_compute(struct ggml_context * ctx, struct ggml_cgraph * cgraph)
1596715991 .nth = n_threads,
1596815992 .wsize = cgraph->work ? ggml_nbytes(cgraph->work) : 0,
1596915993 .wdata = cgraph->work ? cgraph->work->data : NULL,
15994+ .aic = &state_shared.aic,
1597015995 },
1597115996 .node = NULL,
1597215997 .shared = &state_shared,
@@ -16308,6 +16333,7 @@ void ggml_graph_compute(struct ggml_context * ctx, struct ggml_cgraph * cgraph)
1630816333 /*.nth =*/ node->n_tasks,
1630916334 /*.wsize =*/ cgraph->work ? ggml_nbytes(cgraph->work) : 0,
1631016335 /*.wdata =*/ cgraph->work ? cgraph->work->data : NULL,
16336+ /*.aic =*/ &state_shared.aic,
1631116337 };
1631216338
1631316339 ggml_compute_forward(¶ms, node);
@@ -16331,6 +16357,7 @@ void ggml_graph_compute(struct ggml_context * ctx, struct ggml_cgraph * cgraph)
1633116357 .nth = node->n_tasks,
1633216358 .wsize = cgraph->work ? ggml_nbytes(cgraph->work) : 0,
1633316359 .wdata = cgraph->work ? cgraph->work->data : NULL,
16360+ .aic = &state_shared.aic,
1633416361 };
1633516362 workers[j].node = node;
1633616363 }
@@ -16346,6 +16373,7 @@ void ggml_graph_compute(struct ggml_context * ctx, struct ggml_cgraph * cgraph)
1634616373 }
1634716374
1634816375 params.type = GGML_TASK_COMPUTE;
16376+ params.aic = &state_shared.aic;
1634916377 ggml_compute_forward(¶ms, node);
1635016378
1635116379 // wait for thread pool
@@ -16386,6 +16414,7 @@ void ggml_graph_compute(struct ggml_context * ctx, struct ggml_cgraph * cgraph)
1638616414 .nth = node->n_tasks,
1638716415 .wsize = cgraph->work ? ggml_nbytes(cgraph->work) : 0,
1638816416 .wdata = cgraph->work ? cgraph->work->data : NULL,
16417+ .aic = &state_shared.aic,
1638916418 };
1639016419 workers[j].node = node;
1639116420 }
0 commit comments