static_embeddings 1.5.6 → 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: 550531f7573a8d05e8d5a3a1ae0fa301c01d77b238573ae11834797e8ac44a0f
4
- data.tar.gz: 57f487c729296e3a858604dc64aa146aa6dd6e372a45961d90a61564e3c1b117
3
+ metadata.gz: cbb2b16d03e01ba91c8c856890e98537ff81c4b4961a4d4172dc2e8a27fb46e3
4
+ data.tar.gz: d182451276da091e5410fa5dcbf93ec08e773bfa51cc6226f0c244db132e3656
5
5
  SHA512:
6
- metadata.gz: 52162c96d458dffaaec8498cd712678b4727b29ddaa66eadf7834893113a6bd05f636cc47a2f84d969f76eb4651fe57664212fdb4ac2925449827b9d3a69a9bf
7
- data.tar.gz: 115a0b0f3ff9d82cea099fc0ee24385034d8bcc66ca4ff9337f2213608ee4d611215b6d3400fe39aecf562cf201f5f5044eab7f9863fbdc813362c0af0eb7739
6
+ metadata.gz: 54d96917d4a2fd738787ee12bd57a63f3793893a4abe3e59a9b860efe8508a895cb4d1cbd865f4f5692af1b2aa46eea21b17b55ed090b98a9af8df59946feadc
7
+ data.tar.gz: da73a4ead8792691b1e8433ecb7487f121e1dda88c61054e56f0f05b56c43f922a49643f1668da4c34be1258f654f134975cae5db875075f2a99e9bd2ea5256a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
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
+
11
+ ## 1.5.7
12
+
13
+ ### Fixed
14
+
15
+ - Model mappings are no longer closed while embedding, warmup, or token-ID
16
+ operations are using them without the GVL. `Model#close` raises
17
+ `StaticEmbeddings::Error` while such an operation is active.
18
+ - Tokenizer code-point writes now verify the capacity invariant after growth.
19
+ - Resolved Clang conversion warnings and formatting issues in the native code.
20
+
3
21
  ## 1.5.6
4
22
 
5
23
  Multi-source WordPiece release. The native `.semb` v3 runtime is unchanged; new
@@ -5,9 +5,8 @@
5
5
  #include <string.h>
6
6
 
7
7
  static const char *const se_alloc_category_names[SE_ALLOC_CATEGORY_COUNT] = {
8
- "unknown", "scratch", "batch_input", "batch_output",
9
- "batch_stats", "batch_index", "token_ids", "topk_query",
10
- "topk_best", "topk_matrix_copy", "format_validate", "model_file"};
8
+ "unknown", "scratch", "batch_input", "batch_output", "batch_stats", "batch_index",
9
+ "token_ids", "topk_query", "topk_best", "topk_matrix_copy", "format_validate", "model_file"};
11
10
 
12
11
  const char *se_alloc_category_name(se_alloc_category_t category) {
13
12
  if ((unsigned)category >= SE_ALLOC_CATEGORY_COUNT)
@@ -176,7 +175,8 @@ void *se_alloc_stats_realloc(se_alloc_category_t category, void *ptr, size_t byt
176
175
  if (old_header->h.magic != SE_ALLOC_STATS_MAGIC)
177
176
  abort();
178
177
 
179
- se_alloc_category_t old_category = normalize_category((se_alloc_category_t)old_header->h.category);
178
+ se_alloc_category_t old_category =
179
+ normalize_category((se_alloc_category_t)old_header->h.category);
180
180
  size_t old_bytes = old_header->h.size;
181
181
  se_alloc_header_t *new_header = (se_alloc_header_t *)realloc(old_header, total);
182
182
  if (!new_header)
@@ -223,8 +223,7 @@ void se_alloc_stats_snapshot(se_alloc_stats_t out[SE_ALLOC_CATEGORY_COUNT]) {
223
223
  for (size_t i = 0; i < SE_ALLOC_CATEGORY_COUNT; i++) {
224
224
  out[i].current_bytes = atomic_load_size(&se_alloc_stats[i].current_bytes);
225
225
  out[i].peak_bytes = atomic_load_size(&se_alloc_stats[i].peak_bytes);
226
- out[i].total_allocated_bytes =
227
- atomic_load_size(&se_alloc_stats[i].total_allocated_bytes);
226
+ out[i].total_allocated_bytes = atomic_load_size(&se_alloc_stats[i].total_allocated_bytes);
228
227
  out[i].total_freed_bytes = atomic_load_size(&se_alloc_stats[i].total_freed_bytes);
229
228
  out[i].alloc_count = atomic_load_size(&se_alloc_stats[i].alloc_count);
230
229
  out[i].realloc_count = atomic_load_size(&se_alloc_stats[i].realloc_count);
@@ -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)
@@ -35,7 +35,7 @@ static void write_u16le(uint8_t *dst, uint16_t v) {
35
35
  }
36
36
 
37
37
  static uint16_t read_u16le(const uint8_t *src) {
38
- return (uint16_t)src[0] | ((uint16_t)src[1] << 8);
38
+ return (uint16_t)((uint16_t)src[0] | ((uint16_t)src[1] << 8));
39
39
  }
40
40
 
41
41
  uint16_t se_float_to_f16_bits(float value) {
@@ -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) {
@@ -512,6 +512,8 @@ static int append_segment_cp(token_state_t *st, uint32_t cp) {
512
512
  st->segment_ascii = 0;
513
513
  if (!grow_u32(&st->scratch->cps, &st->scratch->cps_cap, st->segment_len + 1))
514
514
  return 0;
515
+ if (st->segment_len >= st->scratch->cps_cap)
516
+ return 0;
515
517
  st->scratch->cps[st->segment_len++] = cp;
516
518
  return 1;
517
519
  }
@@ -906,6 +908,10 @@ static se_status_t tokenize_ascii_run(token_state_t *st, const uint8_t *input, s
906
908
  return oom(st, "building token segment");
907
909
  }
908
910
  }
911
+ if (st->segment_len >= sc->cps_cap) {
912
+ *ip = i;
913
+ return oom(st, "building token segment");
914
+ }
909
915
  sc->cps[st->segment_len++] =
910
916
  (lc && b >= 'A' && b <= 'Z') ? (uint32_t)(b + 32u) : (uint32_t)b;
911
917
  i++;
@@ -948,7 +954,7 @@ static se_status_t tokenize_ascii_run(token_state_t *st, const uint8_t *input, s
948
954
  se_status_t se_tokenize(const se_model_t *model, se_scratch_t *sc, const uint8_t *input,
949
955
  size_t input_len, uint32_t max_tokens, se_token_limit_t limit_mode,
950
956
  se_token_stats_t *stats, se_error_t *err,
951
- volatile sig_atomic_t *cancelled) {
957
+ se_cancel_flag_t *cancelled) {
952
958
  memset(stats, 0, sizeof(*stats));
953
959
 
954
960
  token_state_t st;
@@ -73,8 +73,7 @@ float se_dot_product_f32(const float *q, const float *row, size_t dim) {
73
73
  return dot;
74
74
  }
75
75
 
76
- float se_dot_and_row_sq_f32(const float *q, const float *row, size_t dim,
77
- float *row_sq_out) {
76
+ float se_dot_and_row_sq_f32(const float *q, const float *row, size_t dim, float *row_sq_out) {
78
77
  size_t j = 0;
79
78
  #if defined(SE_HAVE_NEON)
80
79
  float32x4_t d0 = vdupq_n_f32(0.0f);
@@ -196,7 +195,7 @@ static float cosine_score(float dot, float row_sq, float inv_query_norm) {
196
195
  void *se_topk_execute(void *arg) {
197
196
  se_topk_job_t *job = (se_topk_job_t *)arg;
198
197
  for (size_t r = 0; r < job->rows; r++) {
199
- if ((r & 1023u) == 0 && job->cancelled)
198
+ if ((r & 1023u) == 0 && se_cancel_requested(&job->cancelled))
200
199
  return NULL;
201
200
  float score;
202
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>
@@ -93,6 +92,7 @@ RUBY_FUNC_EXPORTED void Init_static_embeddings(void);
93
92
  typedef struct {
94
93
  se_model_t model;
95
94
  int open;
95
+ unsigned int active_ops;
96
96
  } model_wrapper_t;
97
97
 
98
98
  static void model_free(void *ptr) {
@@ -177,7 +177,7 @@ static void check_text_encoding_mode(VALUE str, long index, se_encoding_validati
177
177
  rb_enc_name(enc));
178
178
  }
179
179
 
180
- int cr = ENC_CODERANGE(str);
180
+ int cr = (int)ENC_CODERANGE(str);
181
181
  if (cr == ENC_CODERANGE_UNKNOWN) {
182
182
  if (mode == SE_VALIDATE_ENCODING_PREFIX)
183
183
  return;
@@ -216,6 +216,7 @@ typedef struct {
216
216
 
217
217
  typedef struct {
218
218
  const se_model_t *model;
219
+ model_wrapper_t *owner;
219
220
  batch_input_t input;
220
221
  uint32_t max_tokens;
221
222
  float *out;
@@ -224,10 +225,12 @@ typedef struct {
224
225
  size_t next_index;
225
226
  int failed;
226
227
  size_t failed_index;
227
- volatile sig_atomic_t cancelled;
228
+ se_cancel_flag_t cancelled;
228
229
  se_error_t error;
229
230
  } batch_job_t;
230
231
 
232
+ static void run_job(batch_job_t *job, size_t total_bytes);
233
+
231
234
  static void job_fail(batch_job_t *job, se_error_t err, size_t index) {
232
235
  if (job->failed)
233
236
  return;
@@ -240,7 +243,7 @@ static void batch_worker_run(batch_job_t *job, se_scratch_t *scratch) {
240
243
  const uint32_t dim = job->model->meta.dim;
241
244
 
242
245
  for (;;) {
243
- if (job->cancelled) {
246
+ if (se_cancel_requested(&job->cancelled)) {
244
247
  se_error_set(&job->error, SE_ERR_INTERNAL, "operation cancelled");
245
248
  job->failed = 1;
246
249
  return;
@@ -289,7 +292,7 @@ static void *batch_execute(void *arg) {
289
292
  static void unblock_cancel(void *arg) {
290
293
  batch_job_t *job = (batch_job_t *)arg;
291
294
  if (job)
292
- job->cancelled = 1;
295
+ se_cancel_request(&job->cancelled);
293
296
  }
294
297
 
295
298
  static VALUE current_fiber_scheduler(void) {
@@ -354,13 +357,28 @@ static VALUE fiber_worker_ensure(VALUE wrapper) {
354
357
  fiber_worker_t *w;
355
358
  TypedData_Get_Struct(wrapper, fiber_worker_t, &fiber_worker_type, w);
356
359
  if (!NIL_P(w->thread)) {
357
- w->job->cancelled = 1;
360
+ se_cancel_request(&w->job->cancelled);
358
361
  rb_funcall(w->thread, id_kill, 0);
359
362
  rb_funcall(w->thread, id_join, 0);
360
363
  }
361
364
  return Qnil;
362
365
  }
363
366
 
367
+ static VALUE run_job_body(VALUE arg) {
368
+ batch_job_t *job = (batch_job_t *)(uintptr_t)arg;
369
+ size_t total_bytes = 0;
370
+ for (size_t i = 0; i < job->input.count; i++)
371
+ total_bytes += job->input.lengths[i];
372
+ run_job(job, total_bytes);
373
+ return Qnil;
374
+ }
375
+
376
+ static VALUE run_job_ensure(VALUE arg) {
377
+ batch_job_t *job = (batch_job_t *)(uintptr_t)arg;
378
+ job->owner->active_ops--;
379
+ return Qnil;
380
+ }
381
+
364
382
  static void run_job(batch_job_t *job, size_t total_bytes) {
365
383
  VALUE scheduler = current_fiber_scheduler();
366
384
 
@@ -386,11 +404,8 @@ static void run_job(batch_job_t *job, size_t total_bytes) {
386
404
 
387
405
  static VALUE protected_run_job(VALUE arg) {
388
406
  batch_job_t *job = (batch_job_t *)(uintptr_t)arg;
389
- size_t total_bytes = 0;
390
- for (size_t i = 0; i < job->input.count; i++)
391
- total_bytes += job->input.lengths[i];
392
- run_job(job, total_bytes);
393
- return Qnil;
407
+ job->owner->active_ops++;
408
+ return rb_ensure(run_job_body, arg, run_job_ensure, arg);
394
409
  }
395
410
 
396
411
  static VALUE model_alloc(VALUE klass) {
@@ -422,6 +437,8 @@ static VALUE model_close(VALUE self) {
422
437
  model_wrapper_t *w;
423
438
  TypedData_Get_Struct(self, model_wrapper_t, &model_type, w);
424
439
  if (w->open) {
440
+ if (w->active_ops != 0)
441
+ rb_raise(eError, "model is busy with an active operation");
425
442
  se_model_close(&w->model);
426
443
  w->open = 0;
427
444
  }
@@ -474,18 +491,40 @@ typedef struct {
474
491
  size_t pages;
475
492
  } warmup_job_t;
476
493
 
494
+ typedef struct {
495
+ VALUE self;
496
+ model_wrapper_t *owner;
497
+ warmup_job_t job;
498
+ } warmup_run_t;
499
+
477
500
  static void *warmup_execute(void *arg) {
478
501
  warmup_job_t *job = (warmup_job_t *)arg;
479
502
  job->pages = se_model_warmup(job->model);
480
503
  return NULL;
481
504
  }
482
505
 
506
+ static VALUE warmup_body(VALUE arg) {
507
+ warmup_run_t *run = (warmup_run_t *)(uintptr_t)arg;
508
+ rb_thread_call_without_gvl(warmup_execute, &run->job, NULL, NULL);
509
+ RB_GC_GUARD(run->self);
510
+ return Qnil;
511
+ }
512
+
513
+ static VALUE warmup_ensure(VALUE arg) {
514
+ warmup_run_t *run = (warmup_run_t *)(uintptr_t)arg;
515
+ run->owner->active_ops--;
516
+ return Qnil;
517
+ }
518
+
483
519
  static VALUE model_warmup(VALUE self) {
484
520
  model_wrapper_t *w = get_model(self);
485
- warmup_job_t job;
486
- job.model = &w->model;
487
- job.pages = 0;
488
- rb_thread_call_without_gvl(warmup_execute, &job, NULL, NULL);
521
+ warmup_run_t run;
522
+ run.self = self;
523
+ run.owner = w;
524
+ run.job.model = &w->model;
525
+ run.job.pages = 0;
526
+ w->active_ops++;
527
+ rb_ensure(warmup_body, (VALUE)(uintptr_t)&run, warmup_ensure, (VALUE)(uintptr_t)&run);
489
528
  RB_GC_GUARD(self);
490
529
  return self;
491
530
  }
@@ -829,6 +868,7 @@ static VALUE embed_texts_internal(VALUE self, VALUE texts, int is_array, size_t
829
868
  batch_job_t job;
830
869
  memset(&job, 0, sizeof(job));
831
870
  job.model = model;
871
+ job.owner = w;
832
872
  job.max_tokens = max_tokens;
833
873
  job.out = run.out;
834
874
  job.stats = run.stats;
@@ -844,7 +884,7 @@ static VALUE embed_texts_internal(VALUE self, VALUE texts, int is_array, size_t
844
884
  int state = 0;
845
885
  rb_protect(protected_run_job, (VALUE)(uintptr_t)&job, &state);
846
886
  if (state) {
847
- job.cancelled = 1;
887
+ se_cancel_request(&job.cancelled);
848
888
  free_input(&job.input);
849
889
  embed_run_free(&run);
850
890
  rb_jump_tag(state);
@@ -1110,12 +1150,13 @@ typedef struct {
1110
1150
  size_t n_ids;
1111
1151
  float *out;
1112
1152
  se_token_stats_t stats;
1113
- volatile sig_atomic_t cancelled;
1153
+ se_cancel_flag_t cancelled;
1114
1154
  se_error_t error;
1115
1155
  } ids_job_t;
1116
1156
 
1117
1157
  typedef struct {
1118
1158
  VALUE ids_value;
1159
+ model_wrapper_t *owner;
1119
1160
  const se_model_t *model;
1120
1161
  uint32_t max_tokens;
1121
1162
  uint32_t *ids;
@@ -1126,6 +1167,7 @@ typedef struct {
1126
1167
  se_token_stats_t *stats_out;
1127
1168
  se_token_stats_t stats;
1128
1169
  int truncated;
1170
+ int active;
1129
1171
  } ids_run_t;
1130
1172
 
1131
1173
  typedef struct {
@@ -1157,7 +1199,7 @@ static void *ids_execute(void *arg) {
1157
1199
  static void ids_unblock_cancel(void *arg) {
1158
1200
  ids_job_t *job = (ids_job_t *)arg;
1159
1201
  if (job)
1160
- job->cancelled = 1;
1202
+ se_cancel_request(&job->cancelled);
1161
1203
  }
1162
1204
 
1163
1205
  static VALUE embed_token_ids_body(VALUE arg) {
@@ -1197,9 +1239,13 @@ static VALUE embed_token_ids_body(VALUE arg) {
1197
1239
  se_error_clear(&job.error);
1198
1240
 
1199
1241
  if (run->n >= SE_IDS_GVL_UNLOCK_THRESHOLD) {
1242
+ run->owner->active_ops++;
1243
+ run->active = 1;
1200
1244
  rb_thread_call_without_gvl(ids_execute, &job, ids_unblock_cancel, &job);
1245
+ run->owner->active_ops--;
1246
+ run->active = 0;
1201
1247
  rb_thread_check_ints();
1202
- if (job.cancelled)
1248
+ if (se_cancel_requested(&job.cancelled))
1203
1249
  rb_raise(rb_eInterrupt, "operation cancelled");
1204
1250
  } else {
1205
1251
  ids_execute(&job);
@@ -1225,6 +1271,8 @@ static VALUE embed_token_ids_body(VALUE arg) {
1225
1271
 
1226
1272
  static VALUE embed_token_ids_ensure(VALUE arg) {
1227
1273
  ids_run_t *run = (ids_run_t *)(uintptr_t)arg;
1274
+ if (run->active)
1275
+ run->owner->active_ops--;
1228
1276
  se_free(run->ids);
1229
1277
  se_free(run->out);
1230
1278
  run->ids = NULL;
@@ -1280,6 +1328,7 @@ static VALUE embed_token_ids_value(VALUE self, VALUE ids_value, VALUE max_tokens
1280
1328
  ids_run_t run;
1281
1329
  memset(&run, 0, sizeof(run));
1282
1330
  run.ids_value = ids_value;
1331
+ run.owner = w;
1283
1332
  run.model = &w->model;
1284
1333
  run.max_tokens = max_tokens;
1285
1334
  run.n = n;
@@ -1346,7 +1395,7 @@ static int ptr_is_float_aligned(const void *ptr) {
1346
1395
  static void topk_unblock_cancel(void *arg) {
1347
1396
  se_topk_job_t *job = (se_topk_job_t *)arg;
1348
1397
  if (job)
1349
- job->cancelled = 1;
1398
+ se_cancel_request(&job->cancelled);
1350
1399
  }
1351
1400
 
1352
1401
  static VALUE topk_body(VALUE arg) {
@@ -1375,7 +1424,7 @@ static VALUE topk_body(VALUE arg) {
1375
1424
  rb_thread_check_ints();
1376
1425
  }
1377
1426
 
1378
- if (run->job.cancelled)
1427
+ if (se_cancel_requested(&run->job.cancelled))
1379
1428
  rb_raise(rb_eInterrupt, "operation cancelled");
1380
1429
 
1381
1430
  VALUE result = rb_ary_new_capa(run->job.k);
@@ -1,3 +1,3 @@
1
1
  module StaticEmbeddings
2
- VERSION = "1.5.6"
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.6
4
+ version: 1.5.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Haydarov