umappp 0.2.0 → 0.2.2

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.
@@ -1,8 +1,12 @@
1
- // Uniform Manifold Approximation and Projection for Ruby
2
- // https://github.com/kojix2/ruby-umappp
1
+ /*
2
+ * Uniform Manifold Approximation and Projection for Ruby
3
+ * https://github.com/kojix2/ruby-umappp
4
+ */
3
5
 
4
6
  #include <rice/rice.hpp>
5
7
  #include <rice/stl.hpp>
8
+ #include <exception>
9
+ #include <string>
6
10
  #include "numo.hpp"
7
11
  #include "Umap.hpp"
8
12
 
@@ -11,8 +15,45 @@ typedef typename umappp::Umap<Float> Umap;
11
15
 
12
16
  using namespace Rice;
13
17
 
14
- // This function is used to view default parameters from Ruby.
18
+ extern "C" {
19
+ void *rb_thread_call_without_gvl(
20
+ void *(*func)(void *), void *data,
21
+ void (*ubf)(void *), void *ubf_data
22
+ );
23
+ }
24
+
25
+ // Data structure for running UMAP calculation without GVL.
26
+ struct UmapRunData {
27
+ Umap* umap_ptr;
28
+ knncolle::Base<int, Float>* knncolle_ptr;
29
+ int ndim;
30
+ std::vector<Float>* embedding;
31
+ std::string exception_message;
32
+ bool exception_thrown = false;
33
+ };
34
+
35
+ // Callback for UMAP calculation (executed without GVL).
36
+ static void* umap_run_without_gvl(void* data) {
37
+ UmapRunData* run_data = static_cast<UmapRunData*>(data);
38
+ try {
39
+ auto status = run_data->umap_ptr->initialize(
40
+ run_data->knncolle_ptr,
41
+ run_data->ndim,
42
+ run_data->embedding->data()
43
+ );
44
+ int epoch_limit = 0;
45
+ status.run(epoch_limit);
46
+ } catch (const std::exception& e) {
47
+ run_data->exception_message = e.what();
48
+ run_data->exception_thrown = true;
49
+ } catch (...) {
50
+ run_data->exception_message = "Unknown exception occurred in UMAP calculation.";
51
+ run_data->exception_thrown = true;
52
+ }
53
+ return nullptr;
54
+ }
15
55
 
56
+ // Returns default parameters from the Umappp C++ library.
16
57
  Hash umappp_default_parameters(Object self)
17
58
  {
18
59
  Hash d;
@@ -36,8 +77,7 @@ Hash umappp_default_parameters(Object self)
36
77
  return d;
37
78
  }
38
79
 
39
- // Function to perform umap.
40
-
80
+ // Main function to perform UMAP.
41
81
  Object umappp_run(
42
82
  Object self,
43
83
  Hash params,
@@ -45,8 +85,6 @@ Object umappp_run(
45
85
  int ndim,
46
86
  int nn_method)
47
87
  {
48
- // Parameters are taken from a Ruby Hash object.
49
- // If there is key, set the value.
50
88
  if (ndim < 1)
51
89
  {
52
90
  throw std::runtime_error("ndim is less than 1");
@@ -166,8 +204,6 @@ Object umappp_run(
166
204
  umap_ptr->set_parallel_optimization(parallel_optimization);
167
205
  }
168
206
 
169
- // initialize_from_matrix
170
-
171
207
  const float *y = data.read_ptr();
172
208
  size_t *shape = data.shape();
173
209
 
@@ -190,13 +226,25 @@ Object umappp_run(
190
226
 
191
227
  std::vector<Float> embedding(ndim * nobs);
192
228
 
193
- auto status = umap_ptr->initialize(knncolle_ptr.get(), ndim, embedding.data());
194
-
195
- int epoch_limit = 0;
196
- // tick is not implemented yet
197
- status.run(epoch_limit);
229
+ // Run UMAP calculation without GVL.
230
+ UmapRunData run_data = {
231
+ umap_ptr.get(),
232
+ knncolle_ptr.get(),
233
+ ndim,
234
+ &embedding
235
+ };
236
+
237
+ rb_thread_call_without_gvl(
238
+ umap_run_without_gvl,
239
+ &run_data,
240
+ NULL,
241
+ NULL
242
+ );
243
+
244
+ if (run_data.exception_thrown) {
245
+ throw std::runtime_error(run_data.exception_message);
246
+ }
198
247
 
199
- // it is safe to cast to unsigned int
200
248
  auto na = numo::SFloat({(unsigned int)nobs, (unsigned int)ndim});
201
249
  std::copy(embedding.begin(), embedding.end(), na.write_ptr());
202
250
 
@@ -210,7 +258,7 @@ extern "C" void Init_umappp()
210
258
  .define_singleton_method("umappp_run", &umappp_run)
211
259
  .define_singleton_method("umappp_default_parameters", &umappp_default_parameters);
212
260
  Enum<umappp::InitMethod> init_method =
213
- define_enum<umappp::InitMethod>("InitMethod", rb_mUmappp)
261
+ define_enum<umappp::InitMethod>("InitMethod")
214
262
  .define_value("SPECTRAL", umappp::InitMethod::SPECTRAL)
215
263
  .define_value("SPECTRAL_ONLY", umappp::InitMethod::SPECTRAL_ONLY)
216
264
  .define_value("RANDOM", umappp::InitMethod::RANDOM)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Umappp
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: umappp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - kojix2
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-01-29 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: numo-narray
@@ -28,16 +27,16 @@ dependencies:
28
27
  name: rice
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
- - - "~>"
30
+ - - ">="
32
31
  - !ruby/object:Gem::Version
33
- version: '4.0'
32
+ version: 4.5.0
34
33
  type: :runtime
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
- - - "~>"
37
+ - - ">="
39
38
  - !ruby/object:Gem::Version
40
- version: '4.0'
39
+ version: 4.5.0
41
40
  description: Umappp wrapper for Ruby
42
41
  email:
43
42
  - 2xijok@gmail.com
@@ -443,7 +442,6 @@ homepage: https://github.com/kojix2/ruby-umappp
443
442
  licenses:
444
443
  - BSD-2-Clause
445
444
  metadata: {}
446
- post_install_message:
447
445
  rdoc_options: []
448
446
  require_paths:
449
447
  - lib
@@ -458,8 +456,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
458
456
  - !ruby/object:Gem::Version
459
457
  version: '0'
460
458
  requirements: []
461
- rubygems_version: 3.5.4
462
- signing_key:
459
+ rubygems_version: 3.6.7
463
460
  specification_version: 4
464
461
  summary: Umap for Ruby
465
462
  test_files: []