static_embeddings 1.5.7 → 1.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a8e174dd93ba3b3e9ee25047fd28ea5ba980d096a4922c0b8325c366208bff65
4
- data.tar.gz: 741e0cc35791d9a335c82a05aed18e3388232828824168ff59ed1751c281e8a8
3
+ metadata.gz: cbb2b16d03e01ba91c8c856890e98537ff81c4b4961a4d4172dc2e8a27fb46e3
4
+ data.tar.gz: d182451276da091e5410fa5dcbf93ec08e773bfa51cc6226f0c244db132e3656
5
5
  SHA512:
6
- metadata.gz: 58462ed4c203fb657630d092e1a4aa85857e5d44106bb97feae26f12579fc4b6d88d20632e462624ad0cb93e1d0d0e735f91ee12aaec80b637d29b313e6dc53d
7
- data.tar.gz: 80e9897969dfe6aace3d851f1a11ffb6610b628cddc35239301a676b2ce32d97d1a8a614ae6dca0526703e61d6d813af89965d0906c593392e66cdd25f7e16da
6
+ metadata.gz: 54d96917d4a2fd738787ee12bd57a63f3793893a4abe3e59a9b860efe8508a895cb4d1cbd865f4f5692af1b2aa46eea21b17b55ed090b98a9af8df59946feadc
7
+ data.tar.gz: da73a4ead8792691b1e8433ecb7487f121e1dda88c61054e56f0f05b56c43f922a49643f1668da4c34be1258f654f134975cae5db875075f2a99e9bd2ea5256a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.5.8
4
+
5
+ ### Fixed
6
+
7
+ - Cancellation flags shared by Ruby's unblock callback and native worker threads now use
8
+ atomic loads and stores, removing a C data race during interrupted embedding, tokenization,
9
+ and top-k operations.
10
+
3
11
  ## 1.5.7
4
12
 
5
13
  ### Fixed
@@ -119,7 +119,7 @@ void se_l2_normalize(float *vec, uint32_t dim) {
119
119
 
120
120
  static se_status_t embed_ids_core(const se_model_t *model, se_scratch_t *sc, const uint32_t *ids,
121
121
  size_t n, float *out, se_error_t *err,
122
- volatile sig_atomic_t *cancelled) {
122
+ se_cancel_flag_t *cancelled) {
123
123
  const uint32_t dim = model->meta.dim;
124
124
  float *acc = sc->acc;
125
125
  memset(acc, 0, (size_t)dim * sizeof(float));
@@ -129,7 +129,7 @@ static se_status_t embed_ids_core(const se_model_t *model, se_scratch_t *sc, con
129
129
 
130
130
  size_t used = 0;
131
131
  for (size_t i = 0; i < n; i++) {
132
- if (((i & 255u) == 0) && cancelled && *cancelled) {
132
+ if (((i & 255u) == 0) && se_cancel_requested(cancelled)) {
133
133
  se_error_set(err, SE_ERR_INTERNAL, "operation cancelled");
134
134
  return SE_ERR_INTERNAL;
135
135
  }
@@ -179,7 +179,7 @@ static se_status_t embed_ids_core(const se_model_t *model, se_scratch_t *sc, con
179
179
 
180
180
  se_status_t se_embed_ids(const se_model_t *model, se_scratch_t *sc, const uint32_t *ids,
181
181
  size_t n_ids, float *out, se_token_stats_t *stats, se_error_t *err,
182
- volatile sig_atomic_t *cancelled) {
182
+ se_cancel_flag_t *cancelled) {
183
183
  if (n_ids > UINT32_MAX) {
184
184
  se_error_set(err, SE_ERR_OOM, "too many token ids");
185
185
  return SE_ERR_OOM;
@@ -196,7 +196,7 @@ se_status_t se_embed_ids(const se_model_t *model, se_scratch_t *sc, const uint32
196
196
 
197
197
  se_status_t se_embed_one(const se_model_t *model, se_scratch_t *sc, const uint8_t *input,
198
198
  size_t input_len, uint32_t max_tokens, float *out, se_token_stats_t *stats,
199
- se_error_t *err, volatile sig_atomic_t *cancelled) {
199
+ se_error_t *err, se_cancel_flag_t *cancelled) {
200
200
  se_status_t rc = se_tokenize(model, sc, input, input_len, max_tokens, SE_TOKEN_LIMIT_USABLE,
201
201
  stats, err, cancelled);
202
202
  if (rc != SE_OK)
@@ -3,9 +3,18 @@
3
3
 
4
4
  #include <stddef.h>
5
5
  #include <stdint.h>
6
- #include <signal.h>
7
6
  #include <limits.h>
8
7
 
8
+ typedef int se_cancel_flag_t;
9
+
10
+ static inline int se_cancel_requested(const se_cancel_flag_t *flag) {
11
+ return flag && __atomic_load_n(flag, __ATOMIC_RELAXED);
12
+ }
13
+
14
+ static inline void se_cancel_request(se_cancel_flag_t *flag) {
15
+ __atomic_store_n(flag, 1, __ATOMIC_RELAXED);
16
+ }
17
+
9
18
  #define SE_MAGIC "SEMBv1\0\0"
10
19
  #define SE_MAGIC_LEN 8
11
20
  #define SE_FORMAT_VERSION 3u
@@ -277,7 +286,7 @@ typedef struct {
277
286
  float *best_score;
278
287
  int cosine;
279
288
  float inv_query_norm;
280
- volatile sig_atomic_t cancelled;
289
+ se_cancel_flag_t cancelled;
281
290
  } se_topk_job_t;
282
291
 
283
292
  SE_STATIC_ASSERT(sizeof(se_vocab_slot_t) == 16, vocab_slot_size);
@@ -415,14 +424,14 @@ typedef enum { SE_TOKEN_LIMIT_RAW = 0, SE_TOKEN_LIMIT_USABLE = 1 } se_token_limi
415
424
 
416
425
  se_status_t se_tokenize(const se_model_t *model, se_scratch_t *scratch, const uint8_t *input,
417
426
  size_t input_len, uint32_t max_tokens, se_token_limit_t limit_mode,
418
- se_token_stats_t *stats, se_error_t *err, volatile sig_atomic_t *cancelled);
427
+ se_token_stats_t *stats, se_error_t *err, se_cancel_flag_t *cancelled);
419
428
 
420
429
  se_status_t se_embed_one(const se_model_t *model, se_scratch_t *scratch, const uint8_t *input,
421
430
  size_t input_len, uint32_t max_tokens, float *out, se_token_stats_t *stats,
422
- se_error_t *err, volatile sig_atomic_t *cancelled);
431
+ se_error_t *err, se_cancel_flag_t *cancelled);
423
432
  se_status_t se_embed_ids(const se_model_t *model, se_scratch_t *scratch, const uint32_t *ids,
424
433
  size_t n_ids, float *out, se_token_stats_t *stats, se_error_t *err,
425
- volatile sig_atomic_t *cancelled);
434
+ se_cancel_flag_t *cancelled);
426
435
 
427
436
  void se_l2_normalize(float *vec, uint32_t dim);
428
437
  size_t se_model_warmup(const se_model_t *model);
@@ -495,11 +495,11 @@ typedef struct {
495
495
  int segment_ascii;
496
496
  se_token_stats_t *stats;
497
497
  se_error_t *err;
498
- volatile sig_atomic_t *cancelled;
498
+ se_cancel_flag_t *cancelled;
499
499
  } token_state_t;
500
500
 
501
501
  static int token_cancelled(const token_state_t *st) {
502
- return st->cancelled && *st->cancelled;
502
+ return se_cancel_requested(st->cancelled);
503
503
  }
504
504
 
505
505
  static se_status_t oom(token_state_t *st, const char *where) {
@@ -954,7 +954,7 @@ static se_status_t tokenize_ascii_run(token_state_t *st, const uint8_t *input, s
954
954
  se_status_t se_tokenize(const se_model_t *model, se_scratch_t *sc, const uint8_t *input,
955
955
  size_t input_len, uint32_t max_tokens, se_token_limit_t limit_mode,
956
956
  se_token_stats_t *stats, se_error_t *err,
957
- volatile sig_atomic_t *cancelled) {
957
+ se_cancel_flag_t *cancelled) {
958
958
  memset(stats, 0, sizeof(*stats));
959
959
 
960
960
  token_state_t st;
@@ -195,7 +195,7 @@ static float cosine_score(float dot, float row_sq, float inv_query_norm) {
195
195
  void *se_topk_execute(void *arg) {
196
196
  se_topk_job_t *job = (se_topk_job_t *)arg;
197
197
  for (size_t r = 0; r < job->rows; r++) {
198
- if ((r & 1023u) == 0 && job->cancelled)
198
+ if ((r & 1023u) == 0 && se_cancel_requested(&job->cancelled))
199
199
  return NULL;
200
200
  float score;
201
201
 
@@ -9,7 +9,6 @@
9
9
  #include <float.h>
10
10
  #include <limits.h>
11
11
  #include <math.h>
12
- #include <signal.h>
13
12
  #include <stdint.h>
14
13
  #include <stdio.h>
15
14
  #include <stdlib.h>
@@ -226,7 +225,7 @@ typedef struct {
226
225
  size_t next_index;
227
226
  int failed;
228
227
  size_t failed_index;
229
- volatile sig_atomic_t cancelled;
228
+ se_cancel_flag_t cancelled;
230
229
  se_error_t error;
231
230
  } batch_job_t;
232
231
 
@@ -244,7 +243,7 @@ static void batch_worker_run(batch_job_t *job, se_scratch_t *scratch) {
244
243
  const uint32_t dim = job->model->meta.dim;
245
244
 
246
245
  for (;;) {
247
- if (job->cancelled) {
246
+ if (se_cancel_requested(&job->cancelled)) {
248
247
  se_error_set(&job->error, SE_ERR_INTERNAL, "operation cancelled");
249
248
  job->failed = 1;
250
249
  return;
@@ -293,7 +292,7 @@ static void *batch_execute(void *arg) {
293
292
  static void unblock_cancel(void *arg) {
294
293
  batch_job_t *job = (batch_job_t *)arg;
295
294
  if (job)
296
- job->cancelled = 1;
295
+ se_cancel_request(&job->cancelled);
297
296
  }
298
297
 
299
298
  static VALUE current_fiber_scheduler(void) {
@@ -358,7 +357,7 @@ static VALUE fiber_worker_ensure(VALUE wrapper) {
358
357
  fiber_worker_t *w;
359
358
  TypedData_Get_Struct(wrapper, fiber_worker_t, &fiber_worker_type, w);
360
359
  if (!NIL_P(w->thread)) {
361
- w->job->cancelled = 1;
360
+ se_cancel_request(&w->job->cancelled);
362
361
  rb_funcall(w->thread, id_kill, 0);
363
362
  rb_funcall(w->thread, id_join, 0);
364
363
  }
@@ -885,7 +884,7 @@ static VALUE embed_texts_internal(VALUE self, VALUE texts, int is_array, size_t
885
884
  int state = 0;
886
885
  rb_protect(protected_run_job, (VALUE)(uintptr_t)&job, &state);
887
886
  if (state) {
888
- job.cancelled = 1;
887
+ se_cancel_request(&job.cancelled);
889
888
  free_input(&job.input);
890
889
  embed_run_free(&run);
891
890
  rb_jump_tag(state);
@@ -1151,7 +1150,7 @@ typedef struct {
1151
1150
  size_t n_ids;
1152
1151
  float *out;
1153
1152
  se_token_stats_t stats;
1154
- volatile sig_atomic_t cancelled;
1153
+ se_cancel_flag_t cancelled;
1155
1154
  se_error_t error;
1156
1155
  } ids_job_t;
1157
1156
 
@@ -1200,7 +1199,7 @@ static void *ids_execute(void *arg) {
1200
1199
  static void ids_unblock_cancel(void *arg) {
1201
1200
  ids_job_t *job = (ids_job_t *)arg;
1202
1201
  if (job)
1203
- job->cancelled = 1;
1202
+ se_cancel_request(&job->cancelled);
1204
1203
  }
1205
1204
 
1206
1205
  static VALUE embed_token_ids_body(VALUE arg) {
@@ -1246,7 +1245,7 @@ static VALUE embed_token_ids_body(VALUE arg) {
1246
1245
  run->owner->active_ops--;
1247
1246
  run->active = 0;
1248
1247
  rb_thread_check_ints();
1249
- if (job.cancelled)
1248
+ if (se_cancel_requested(&job.cancelled))
1250
1249
  rb_raise(rb_eInterrupt, "operation cancelled");
1251
1250
  } else {
1252
1251
  ids_execute(&job);
@@ -1396,7 +1395,7 @@ static int ptr_is_float_aligned(const void *ptr) {
1396
1395
  static void topk_unblock_cancel(void *arg) {
1397
1396
  se_topk_job_t *job = (se_topk_job_t *)arg;
1398
1397
  if (job)
1399
- job->cancelled = 1;
1398
+ se_cancel_request(&job->cancelled);
1400
1399
  }
1401
1400
 
1402
1401
  static VALUE topk_body(VALUE arg) {
@@ -1425,7 +1424,7 @@ static VALUE topk_body(VALUE arg) {
1425
1424
  rb_thread_check_ints();
1426
1425
  }
1427
1426
 
1428
- if (run->job.cancelled)
1427
+ if (se_cancel_requested(&run->job.cancelled))
1429
1428
  rb_raise(rb_eInterrupt, "operation cancelled");
1430
1429
 
1431
1430
  VALUE result = rb_ary_new_capa(run->job.k);
@@ -1,3 +1,3 @@
1
1
  module StaticEmbeddings
2
- VERSION = "1.5.7"
2
+ VERSION = "1.5.8"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: static_embeddings
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.7
4
+ version: 1.5.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Haydarov