umappp 0.2.1 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d88fcf9fcf8f61232a094afbf62a7aa421c564e644a854bd2efc1ba94dd1ab02
4
- data.tar.gz: a92531b8da81479a4844ec5f5073423eefdf3fb9d32bed6f7cbe867771116087
3
+ metadata.gz: 715a0cccadbfa68578e1ff6b4998f539313fc31ede7dc1da6c28f51e4396ea91
4
+ data.tar.gz: '07851a541e04c0da5647b9787a889de05ed8d28605818a657b82eebed1b1ba95'
5
5
  SHA512:
6
- metadata.gz: c56ce6be1fe5d9f296b512121be5e94cd844d2ea76ec75ad8e3224ace4023a45146da5cfe4fa779d557c99afbce85a22b951cd2b21a8b1f4f151c5911b13d12a
7
- data.tar.gz: 21be7903f3aa0f03c0a60bf011415f115501e6741a94791465a6e25789ed2c411aed87042b11eeb15aa8ac43d39dff9000a30a7c79cdd0de1b310bd7f5b30044
6
+ metadata.gz: cee6f62c119793903786a0b983c7861f55d27a15b553846ae88d95fd40a335b01c0666e4cdb87b55d4b91218c5e48c5bda8304502716349b02453e7fdbdf5c04
7
+ data.tar.gz: 9cc07b731ead37a256335ae4067b95c41a008bd46bd643b7c82cd36158d26e0b65dcc536c017231ad1368a9b87c95fd02f1611fb2951a01886e18b95467319f4
@@ -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
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Umappp
4
- VERSION = "0.2.1"
4
+ VERSION = "0.2.2"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: umappp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - kojix2