faiss 0.1.7 → 0.2.0

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: f6fb14299c0b91d6ddaf74ca2fa2d6895e8621249a5351683b109f35866ab541
4
- data.tar.gz: 2ec9d11faf8f3f1af7790d1f39e31cb92d8a79d2539fa7c935dbda63f3052d8c
3
+ metadata.gz: 04246f7b765dc5680223f91ecc5c0951f6328411dcaf443c4ae88819c17b26a7
4
+ data.tar.gz: 81698c65e8cca4d7794253775ef06f6e84af005b8dac2872d5d3057a868638ac
5
5
  SHA512:
6
- metadata.gz: 5afa3a7ca6947fad6f5a4f7693b524411875d212079621bc72bda73df36fdf090fcb566b83248302a83ecb38ee04189c57c812eaad4ffc99f94840eaf3abfd28
7
- data.tar.gz: c29cf727d683f82e530ba1788630ae546ddb4470f3145f0a4dd1b6afe31555bb9363dfa52cc2a5e005a077f6e2aae24b3dc1aa44d1ff9c50fc9269987df0ec87
6
+ metadata.gz: 6ad4dcb525a55f0b6743fddeb856d6132c8a518eb92be3dc2ce57302ff05b921fb3ba517aecc76bde78aa6e8bf11d9199fa97cbfe4f3a00e4d466d47f0cabe14
7
+ data.tar.gz: b333df087e863c8ee828b66c1611d8576976064419403710b0b238346d46cc58e69f1c2c708e35bdbc995754b02f50a976389bb0eb102273e7b9f92d771ac395
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.2.0 (2021-05-23)
2
+
3
+ - Improved performance
4
+ - Updated to Rice 4
5
+ - Dropped support for Ruby < 2.6
6
+
1
7
  ## 0.1.7 (2021-03-26)
2
8
 
3
9
  - Added `IndexScalarQuantizer` and `IndexIVFScalarQuantizer`
data/ext/faiss/ext.cpp CHANGED
@@ -1,4 +1,4 @@
1
- #include <rice/Module.hpp>
1
+ #include "utils.h"
2
2
 
3
3
  void init_index(Rice::Module& m);
4
4
  void init_index_binary(Rice::Module& m);
data/ext/faiss/extconf.rb CHANGED
@@ -4,14 +4,17 @@ abort "BLAS not found" unless have_library("blas")
4
4
  abort "LAPACK not found" unless have_library("lapack")
5
5
  abort "OpenMP not found" unless have_library("omp") || have_library("gomp")
6
6
 
7
- $CXXFLAGS << " -std=c++11 -DFINTEGER=int " << with_config("optflags", "-march=native")
7
+ numo = $LOAD_PATH.find { |v| File.exist?("#{v}/numo/numo/narray.h") }
8
+ abort "Numo not found" unless numo && find_header("numo/narray.h", "#{numo}/numo")
9
+
10
+ $CXXFLAGS << " -std=c++17 $(optflags) -DFINTEGER=int " << with_config("optflags", "-march=native")
8
11
 
9
12
  ext = File.expand_path(".", __dir__)
10
13
  vendor = File.expand_path("../../vendor/faiss", __dir__)
11
14
 
12
15
  $srcs = Dir["{#{ext},#{vendor}/faiss,#{vendor}/faiss/{impl,invlists,utils}}/*.{cpp}"]
13
16
  $objs = $srcs.map { |v| v.sub(/cpp\z/, "o") }
14
- $INCFLAGS << " -I#{vendor}"
17
+ abort "Faiss not found" unless find_header("faiss/Index.h", vendor)
15
18
  $VPATH << vendor
16
19
 
17
20
  create_makefile("faiss/ext")
data/ext/faiss/index.cpp CHANGED
@@ -10,109 +10,142 @@
10
10
  #include <faiss/index_io.h>
11
11
  #include <faiss/AutoTune.h>
12
12
 
13
- #include <rice/Array.hpp>
14
- #include <rice/Constructor.hpp>
15
- #include <rice/Module.hpp>
16
-
17
13
  #include "utils.h"
18
14
 
19
- template<>
20
- faiss::MetricType from_ruby<faiss::MetricType>(Rice::Object x)
21
- {
22
- auto s = x.to_s().str();
23
- if (s == "inner_product") {
24
- return faiss::METRIC_INNER_PRODUCT;
25
- } else if (s == "l2") {
26
- return faiss::METRIC_L2;
27
- } else {
28
- // TODO throw argument error
29
- throw std::runtime_error("Invalid metric: " + s);
30
- }
31
- }
32
-
33
- template<>
34
- faiss::ScalarQuantizer::QuantizerType from_ruby<faiss::ScalarQuantizer::QuantizerType>(Rice::Object x)
35
- {
36
- auto s = x.to_s().str();
37
- if (s == "qt_8bit") {
38
- return faiss::ScalarQuantizer::QT_8bit;
39
- } else if (s == "qt_4bit") {
40
- return faiss::ScalarQuantizer::QT_4bit;
41
- } else if (s == "qt_8bit_uniform") {
42
- return faiss::ScalarQuantizer::QT_8bit_uniform;
43
- } else if (s == "qt_4bit_uniform") {
44
- return faiss::ScalarQuantizer::QT_4bit_uniform;
45
- } else if (s == "qt_fp16") {
46
- return faiss::ScalarQuantizer::QT_fp16;
47
- } else if (s == "qt_8bit_direct") {
48
- return faiss::ScalarQuantizer::QT_8bit_direct;
49
- } else if (s == "qt_6bit") {
50
- return faiss::ScalarQuantizer::QT_6bit;
51
- } else {
52
- // TODO throw argument error
53
- throw std::runtime_error("Invalid quantizer type: " + s);
54
- }
15
+ namespace Rice::detail {
16
+ template<>
17
+ struct Type<faiss::MetricType>
18
+ {
19
+ static bool verify()
20
+ {
21
+ return true;
22
+ }
23
+ };
24
+
25
+ template<>
26
+ class From_Ruby<faiss::MetricType>
27
+ {
28
+ public:
29
+ From_Ruby() = default;
30
+
31
+ From_Ruby(Arg* arg) : arg_(arg)
32
+ {
33
+ }
34
+
35
+ faiss::MetricType convert(VALUE x)
36
+ {
37
+ if (x == Qnil && this->arg_ && this->arg_->hasDefaultValue()) {
38
+ return this->arg_->defaultValue<faiss::MetricType>();
39
+ }
40
+
41
+ auto s = Object(x).to_s().str();
42
+ if (s == "inner_product") {
43
+ return faiss::METRIC_INNER_PRODUCT;
44
+ } else if (s == "l2") {
45
+ return faiss::METRIC_L2;
46
+ } else {
47
+ throw Rice::Exception(rb_eArgError, "Invalid metric: %s", s.c_str());
48
+ }
49
+ }
50
+
51
+ private:
52
+ Arg* arg_;
53
+ };
54
+
55
+ template<>
56
+ struct Type<faiss::ScalarQuantizer::QuantizerType>
57
+ {
58
+ static bool verify()
59
+ {
60
+ return true;
61
+ }
62
+ };
63
+
64
+ template<>
65
+ class From_Ruby<faiss::ScalarQuantizer::QuantizerType>
66
+ {
67
+ public:
68
+ faiss::ScalarQuantizer::QuantizerType convert(VALUE x)
69
+ {
70
+ auto s = Object(x).to_s().str();
71
+ if (s == "qt_8bit") {
72
+ return faiss::ScalarQuantizer::QT_8bit;
73
+ } else if (s == "qt_4bit") {
74
+ return faiss::ScalarQuantizer::QT_4bit;
75
+ } else if (s == "qt_8bit_uniform") {
76
+ return faiss::ScalarQuantizer::QT_8bit_uniform;
77
+ } else if (s == "qt_4bit_uniform") {
78
+ return faiss::ScalarQuantizer::QT_4bit_uniform;
79
+ } else if (s == "qt_fp16") {
80
+ return faiss::ScalarQuantizer::QT_fp16;
81
+ } else if (s == "qt_8bit_direct") {
82
+ return faiss::ScalarQuantizer::QT_8bit_direct;
83
+ } else if (s == "qt_6bit") {
84
+ return faiss::ScalarQuantizer::QT_6bit;
85
+ } else {
86
+ throw Rice::Exception(rb_eArgError, "Invalid quantizer type: %s", s.c_str());
87
+ }
88
+ }
89
+ };
55
90
  }
56
91
 
57
92
  void init_index(Rice::Module& m) {
58
93
  Rice::define_class_under<faiss::Index>(m, "Index")
59
94
  .define_method(
60
95
  "d",
61
- *[](faiss::Index &self) {
96
+ [](faiss::Index &self) {
62
97
  return self.d;
63
98
  })
64
99
  .define_method(
65
100
  "trained?",
66
- *[](faiss::Index &self) {
101
+ [](faiss::Index &self) {
67
102
  return self.is_trained;
68
103
  })
69
104
  .define_method(
70
105
  "ntotal",
71
- *[](faiss::Index &self) {
106
+ [](faiss::Index &self) {
72
107
  return self.ntotal;
73
108
  })
74
109
  .define_method(
75
- "_train",
76
- *[](faiss::Index &self, int64_t n, Rice::Object o) {
77
- const float *x = float_array(o);
78
- self.train(n, x);
110
+ "train",
111
+ [](faiss::Index &self, numo::SFloat objects) {
112
+ auto n = check_shape(objects, self.d);
113
+ self.train(n, objects.read_ptr());
79
114
  })
80
115
  .define_method(
81
- "_add",
82
- *[](faiss::Index &self, int64_t n, Rice::Object o) {
83
- const float *x = float_array(o);
84
- self.add(n, x);
116
+ "add",
117
+ [](faiss::Index &self, numo::SFloat objects) {
118
+ auto n = check_shape(objects, self.d);
119
+ self.add(n, objects.read_ptr());
85
120
  })
86
121
  .define_method(
87
- "_search",
88
- *[](faiss::Index &self, int64_t n, Rice::Object o, int64_t k) {
89
- const float *x = float_array(o);
90
- float *distances = new float[k * n];
91
- int64_t *labels = new int64_t[k * n];
122
+ "search",
123
+ [](faiss::Index &self, numo::SFloat objects, size_t k) {
124
+ auto n = check_shape(objects, self.d);
92
125
 
93
- self.search(n, x, k, distances, labels);
126
+ auto distances = numo::SFloat({n, k});
127
+ auto labels = numo::Int64({n, k});
94
128
 
95
- auto dstr = result(distances, k * n);
96
- auto lstr = result(labels, k * n);
129
+ self.search(n, objects.read_ptr(), k, distances.write_ptr(), labels.write_ptr());
97
130
 
98
131
  Rice::Array ret;
99
- ret.push(dstr);
100
- ret.push(lstr);
132
+ ret.push(distances);
133
+ ret.push(labels);
101
134
  return ret;
102
135
  })
103
136
  .define_method(
104
137
  "nprobe=",
105
- *[](faiss::Index &self, double val) {
138
+ [](faiss::Index &self, double val) {
106
139
  faiss::ParameterSpace().set_index_parameter(&self, "nprobe", val);
107
140
  })
108
141
  .define_method(
109
142
  "save",
110
- *[](faiss::Index &self, const char *fname) {
143
+ [](faiss::Index &self, const char *fname) {
111
144
  faiss::write_index(&self, fname);
112
145
  })
113
- .define_singleton_method(
146
+ .define_singleton_function(
114
147
  "load",
115
- *[](const char *fname) {
148
+ [](const char *fname) {
116
149
  return faiss::read_index(fname);
117
150
  });
118
151
 
@@ -123,10 +156,10 @@ void init_index(Rice::Module& m) {
123
156
  .define_constructor(Rice::Constructor<faiss::IndexFlatIP, int64_t>());
124
157
 
125
158
  Rice::define_class_under<faiss::IndexHNSWFlat, faiss::Index>(m, "IndexHNSWFlat")
126
- .define_constructor(Rice::Constructor<faiss::IndexHNSWFlat, int, int, faiss::MetricType>(), (Rice::Arg("d"), Rice::Arg("M"), Rice::Arg("metric") = faiss::METRIC_L2));
159
+ .define_constructor(Rice::Constructor<faiss::IndexHNSWFlat, int, int, faiss::MetricType>(), Rice::Arg("d"), Rice::Arg("M"), Rice::Arg("metric") = faiss::METRIC_L2);
127
160
 
128
161
  Rice::define_class_under<faiss::IndexIVFFlat, faiss::Index>(m, "IndexIVFFlat")
129
- .define_constructor(Rice::Constructor<faiss::IndexIVFFlat, faiss::Index*, size_t, size_t, faiss::MetricType>(), (Rice::Arg("quantizer"), Rice::Arg("d"), Rice::Arg("nlist"), Rice::Arg("metric") = faiss::METRIC_L2));
162
+ .define_constructor(Rice::Constructor<faiss::IndexIVFFlat, faiss::Index*, size_t, size_t, faiss::MetricType>(), Rice::Arg("quantizer"), Rice::Arg("d"), Rice::Arg("nlist"), Rice::Arg("metric") = faiss::METRIC_L2);
130
163
 
131
164
  Rice::define_class_under<faiss::IndexLSH, faiss::Index>(m, "IndexLSH")
132
165
  .define_constructor(Rice::Constructor<faiss::IndexLSH, int64_t, int>());
@@ -141,7 +174,7 @@ void init_index(Rice::Module& m) {
141
174
  .define_constructor(Rice::Constructor<faiss::IndexIVFScalarQuantizer, faiss::Index*, size_t, size_t, faiss::ScalarQuantizer::QuantizerType>());
142
175
 
143
176
  Rice::define_class_under<faiss::IndexIVFPQ, faiss::Index>(m, "IndexIVFPQ")
144
- .define_constructor(Rice::Constructor<faiss::IndexIVFPQ, faiss::Index*, size_t, size_t, size_t, size_t, faiss::MetricType>(), (Rice::Arg("quantizer"), Rice::Arg("d"), Rice::Arg("nlist"), Rice::Arg("M"), Rice::Arg("nbits_per_idx"), Rice::Arg("metric") = faiss::METRIC_L2));
177
+ .define_constructor(Rice::Constructor<faiss::IndexIVFPQ, faiss::Index*, size_t, size_t, size_t, size_t, faiss::MetricType>(), Rice::Arg("quantizer"), Rice::Arg("d"), Rice::Arg("nlist"), Rice::Arg("M"), Rice::Arg("nbits_per_idx"), Rice::Arg("metric") = faiss::METRIC_L2);
145
178
 
146
179
  Rice::define_class_under<faiss::IndexIVFPQR, faiss::Index>(m, "IndexIVFPQR")
147
180
  .define_constructor(Rice::Constructor<faiss::IndexIVFPQR, faiss::Index*, size_t, size_t, size_t, size_t, size_t, size_t>());
@@ -150,7 +183,7 @@ void init_index(Rice::Module& m) {
150
183
  .define_constructor(Rice::Constructor<faiss::ParameterSpace>())
151
184
  .define_method(
152
185
  "set_index_parameter",
153
- *[](faiss::ParameterSpace& self, faiss::Index* index, const std::string& name, double val) {
186
+ [](faiss::ParameterSpace& self, faiss::Index* index, const std::string& name, double val) {
154
187
  self.set_index_parameter(index, name, val);
155
188
  });
156
189
  }
@@ -4,66 +4,60 @@
4
4
  #include <faiss/index_factory.h>
5
5
  #include <faiss/index_io.h>
6
6
 
7
- #include <rice/Array.hpp>
8
- #include <rice/Constructor.hpp>
9
- #include <rice/Module.hpp>
10
-
11
7
  #include "utils.h"
12
8
 
13
9
  void init_index_binary(Rice::Module& m) {
14
10
  Rice::define_class_under<faiss::IndexBinary>(m, "IndexBinary")
15
11
  .define_method(
16
12
  "d",
17
- *[](faiss::IndexBinary &self) {
13
+ [](faiss::IndexBinary &self) {
18
14
  return self.d;
19
15
  })
20
16
  .define_method(
21
17
  "trained?",
22
- *[](faiss::IndexBinary &self) {
18
+ [](faiss::IndexBinary &self) {
23
19
  return self.is_trained;
24
20
  })
25
21
  .define_method(
26
22
  "ntotal",
27
- *[](faiss::IndexBinary &self) {
23
+ [](faiss::IndexBinary &self) {
28
24
  return self.ntotal;
29
25
  })
30
26
  .define_method(
31
- "_train",
32
- *[](faiss::IndexBinary &self, int64_t n, Rice::Object o) {
33
- const uint8_t *x = uint8_array(o);
34
- self.train(n, x);
27
+ "train",
28
+ [](faiss::IndexBinary &self, numo::UInt8 objects) {
29
+ auto n = check_shape(objects, self.d / 8);
30
+ self.train(n, objects.read_ptr());
35
31
  })
36
32
  .define_method(
37
- "_add",
38
- *[](faiss::IndexBinary &self, int64_t n, Rice::Object o) {
39
- const uint8_t *x = uint8_array(o);
40
- self.add(n, x);
33
+ "add",
34
+ [](faiss::IndexBinary &self, numo::UInt8 objects) {
35
+ auto n = check_shape(objects, self.d / 8);
36
+ self.add(n, objects.read_ptr());
41
37
  })
42
38
  .define_method(
43
- "_search",
44
- *[](faiss::IndexBinary &self, int64_t n, Rice::Object o, int64_t k) {
45
- const uint8_t *x = uint8_array(o);
46
- int32_t *distances = new int32_t[k * n];
47
- int64_t *labels = new int64_t[k * n];
39
+ "search",
40
+ [](faiss::IndexBinary &self, numo::UInt8 objects, size_t k) {
41
+ auto n = check_shape(objects, self.d / 8);
48
42
 
49
- self.search(n, x, k, distances, labels);
43
+ auto distances = numo::Int32({n, k});
44
+ auto labels = numo::Int64({n, k});
50
45
 
51
- auto dstr = result(distances, k * n);
52
- auto lstr = result(labels, k * n);
46
+ self.search(n, objects.read_ptr(), k, distances.write_ptr(), labels.write_ptr());
53
47
 
54
48
  Rice::Array ret;
55
- ret.push(dstr);
56
- ret.push(lstr);
49
+ ret.push(distances);
50
+ ret.push(labels);
57
51
  return ret;
58
52
  })
59
53
  .define_method(
60
54
  "save",
61
- *[](faiss::IndexBinary &self, const char *fname) {
55
+ [](faiss::IndexBinary &self, const char *fname) {
62
56
  faiss::write_index_binary(&self, fname);
63
57
  })
64
- .define_singleton_method(
58
+ .define_singleton_function(
65
59
  "load",
66
- *[](const char *fname) {
60
+ [](const char *fname) {
67
61
  return faiss::read_index_binary(fname);
68
62
  });
69
63
 
@@ -73,9 +67,9 @@ void init_index_binary(Rice::Module& m) {
73
67
  Rice::define_class_under<faiss::IndexBinaryIVF, faiss::IndexBinary>(m, "IndexBinaryIVF")
74
68
  .define_constructor(Rice::Constructor<faiss::IndexBinaryIVF, faiss::IndexBinary*, size_t, size_t>());
75
69
 
76
- m.define_singleton_method(
70
+ m.define_singleton_function(
77
71
  "index_binary_factory",
78
- *[](int d, const char *description) {
72
+ [](int d, const char *description) {
79
73
  return faiss::index_binary_factory(d, description);
80
74
  });
81
75
  }
data/ext/faiss/kmeans.cpp CHANGED
@@ -1,36 +1,40 @@
1
1
  #include <faiss/Clustering.h>
2
-
3
- #include <rice/Constructor.hpp>
4
- #include <rice/Module.hpp>
2
+ #include <faiss/IndexFlat.h>
5
3
 
6
4
  #include "utils.h"
7
5
 
8
6
  void init_kmeans(Rice::Module& m) {
9
7
  Rice::define_class_under<faiss::Clustering>(m, "Kmeans")
10
8
  .define_constructor(Rice::Constructor<faiss::Clustering, int, int>())
9
+ .define_method(
10
+ "index",
11
+ [](Rice::Object self) {
12
+ return self.attr_get("@index");
13
+ })
11
14
  .define_method(
12
15
  "d",
13
- *[](faiss::Clustering &self) {
16
+ [](faiss::Clustering &self) {
14
17
  return self.d;
15
18
  })
16
19
  .define_method(
17
20
  "k",
18
- *[](faiss::Clustering &self) {
21
+ [](faiss::Clustering &self) {
19
22
  return self.k;
20
23
  })
21
24
  .define_method(
22
- "_centroids",
23
- *[](faiss::Clustering &self) {
24
- float *centroids = new float[self.k * self.d];
25
- for (size_t i = 0; i < self.centroids.size(); i++) {
26
- centroids[i] = self.centroids[i];
27
- }
28
- return result(centroids, self.k * self.d);
25
+ "centroids",
26
+ [](faiss::Clustering &self) {
27
+ auto centroids = numo::SFloat({self.k, self.d});
28
+ memcpy(centroids.write_ptr(), self.centroids.data(), self.centroids.size() * sizeof(float));
29
+ return centroids;
29
30
  })
30
31
  .define_method(
31
- "_train",
32
- *[](faiss::Clustering &self, int64_t n, Rice::Object o, faiss::Index & index) {
33
- const float *x = float_array(o);
34
- self.train(n, x, index);
32
+ "train",
33
+ [](Rice::Object self, numo::SFloat objects) {
34
+ auto self_ptr = Rice::detail::From_Ruby<faiss::Clustering*>().convert(self.value());
35
+ auto n = check_shape(objects, self_ptr->d);
36
+ auto index = faiss::IndexFlatL2(self_ptr->d);
37
+ self.iv_set("@index", Rice::Object(Rice::detail::To_Ruby<faiss::IndexFlatL2>().convert(index)));
38
+ self_ptr->train(n, objects.read_ptr(), index);
35
39
  });
36
40
  }
@@ -0,0 +1,867 @@
1
+ /*!
2
+ * Numo.hpp v0.1.0
3
+ * https://github.com/ankane/numo.hpp
4
+ * BSD-2-Clause License
5
+ */
6
+
7
+ #pragma once
8
+
9
+ #include <rice/rice.hpp>
10
+ #include <numo/narray.h>
11
+
12
+ namespace numo {
13
+ class NArray {
14
+ public:
15
+ NArray(VALUE v) {
16
+ construct_value(this->dtype(), v);
17
+ }
18
+
19
+ NArray(Rice::Object o) {
20
+ construct_value(this->dtype(), o.value());
21
+ }
22
+
23
+ VALUE value() const {
24
+ return this->_value;
25
+ }
26
+
27
+ size_t ndim() {
28
+ return RNARRAY_NDIM(this->_value);
29
+ }
30
+
31
+ size_t* shape() {
32
+ return RNARRAY_SHAPE(this->_value);
33
+ }
34
+
35
+ size_t size() {
36
+ return RNARRAY_SIZE(this->_value);
37
+ }
38
+
39
+ bool is_contiguous() {
40
+ return nary_check_contiguous(this->_value) == Qtrue;
41
+ }
42
+
43
+ operator Rice::Object() const {
44
+ return Rice::Object(this->_value);
45
+ }
46
+
47
+ const void* read_ptr() {
48
+ if (!is_contiguous()) {
49
+ this->_value = nary_dup(this->_value);
50
+ }
51
+ return nary_get_pointer_for_read(this->_value) + nary_get_offset(this->_value);
52
+ }
53
+
54
+ void* write_ptr() {
55
+ return nary_get_pointer_for_write(this->_value);
56
+ }
57
+
58
+ protected:
59
+ NArray() { }
60
+
61
+ void construct_value(VALUE dtype, VALUE v) {
62
+ this->_value = rb_funcall(dtype, rb_intern("cast"), 1, v);
63
+ }
64
+
65
+ void construct_shape(VALUE dtype, std::initializer_list<size_t> shape) {
66
+ // rb_narray_new doesn't modify shape, but not marked as const
67
+ this->_value = rb_narray_new(dtype, shape.size(), const_cast<size_t*>(shape.begin()));
68
+ }
69
+
70
+ VALUE _value;
71
+
72
+ private:
73
+ VALUE dtype() {
74
+ return numo_cNArray;
75
+ }
76
+ };
77
+
78
+ class SFloat: public NArray {
79
+ public:
80
+ SFloat(VALUE v) {
81
+ construct_value(this->dtype(), v);
82
+ }
83
+
84
+ SFloat(Rice::Object o) {
85
+ construct_value(this->dtype(), o.value());
86
+ }
87
+
88
+ SFloat(std::initializer_list<size_t> shape) {
89
+ construct_shape(this->dtype(), shape);
90
+ }
91
+
92
+ const float* read_ptr() {
93
+ return reinterpret_cast<const float*>(NArray::read_ptr());
94
+ }
95
+
96
+ float* write_ptr() {
97
+ return reinterpret_cast<float*>(NArray::write_ptr());
98
+ }
99
+
100
+ private:
101
+ VALUE dtype() {
102
+ return numo_cSFloat;
103
+ }
104
+ };
105
+
106
+ class DFloat: public NArray {
107
+ public:
108
+ DFloat(VALUE v) {
109
+ construct_value(this->dtype(), v);
110
+ }
111
+
112
+ DFloat(Rice::Object o) {
113
+ construct_value(this->dtype(), o.value());
114
+ }
115
+
116
+ DFloat(std::initializer_list<size_t> shape) {
117
+ construct_shape(this->dtype(), shape);
118
+ }
119
+
120
+ const double* read_ptr() {
121
+ return reinterpret_cast<const double*>(NArray::read_ptr());
122
+ }
123
+
124
+ double* write_ptr() {
125
+ return reinterpret_cast<double*>(NArray::write_ptr());
126
+ }
127
+
128
+ private:
129
+ VALUE dtype() {
130
+ return numo_cDFloat;
131
+ }
132
+ };
133
+
134
+ class Int8: public NArray {
135
+ public:
136
+ Int8(VALUE v) {
137
+ construct_value(this->dtype(), v);
138
+ }
139
+
140
+ Int8(Rice::Object o) {
141
+ construct_value(this->dtype(), o.value());
142
+ }
143
+
144
+ Int8(std::initializer_list<size_t> shape) {
145
+ construct_shape(this->dtype(), shape);
146
+ }
147
+
148
+ const int8_t* read_ptr() {
149
+ return reinterpret_cast<const int8_t*>(NArray::read_ptr());
150
+ }
151
+
152
+ int8_t* write_ptr() {
153
+ return reinterpret_cast<int8_t*>(NArray::write_ptr());
154
+ }
155
+
156
+ private:
157
+ VALUE dtype() {
158
+ return numo_cInt8;
159
+ }
160
+ };
161
+
162
+ class Int16: public NArray {
163
+ public:
164
+ Int16(VALUE v) {
165
+ construct_value(this->dtype(), v);
166
+ }
167
+
168
+ Int16(Rice::Object o) {
169
+ construct_value(this->dtype(), o.value());
170
+ }
171
+
172
+ Int16(std::initializer_list<size_t> shape) {
173
+ construct_shape(this->dtype(), shape);
174
+ }
175
+
176
+ const int16_t* read_ptr() {
177
+ return reinterpret_cast<const int16_t*>(NArray::read_ptr());
178
+ }
179
+
180
+ int16_t* write_ptr() {
181
+ return reinterpret_cast<int16_t*>(NArray::write_ptr());
182
+ }
183
+
184
+ private:
185
+ VALUE dtype() {
186
+ return numo_cInt16;
187
+ }
188
+ };
189
+
190
+ class Int32: public NArray {
191
+ public:
192
+ Int32(VALUE v) {
193
+ construct_value(this->dtype(), v);
194
+ }
195
+
196
+ Int32(Rice::Object o) {
197
+ construct_value(this->dtype(), o.value());
198
+ }
199
+
200
+ Int32(std::initializer_list<size_t> shape) {
201
+ construct_shape(this->dtype(), shape);
202
+ }
203
+
204
+ const int32_t* read_ptr() {
205
+ return reinterpret_cast<const int32_t*>(NArray::read_ptr());
206
+ }
207
+
208
+ int32_t* write_ptr() {
209
+ return reinterpret_cast<int32_t*>(NArray::write_ptr());
210
+ }
211
+
212
+ private:
213
+ VALUE dtype() {
214
+ return numo_cInt32;
215
+ }
216
+ };
217
+
218
+ class Int64: public NArray {
219
+ public:
220
+ Int64(VALUE v) {
221
+ construct_value(this->dtype(), v);
222
+ }
223
+
224
+ Int64(Rice::Object o) {
225
+ construct_value(this->dtype(), o.value());
226
+ }
227
+
228
+ Int64(std::initializer_list<size_t> shape) {
229
+ construct_shape(this->dtype(), shape);
230
+ }
231
+
232
+ const int64_t* read_ptr() {
233
+ return reinterpret_cast<const int64_t*>(NArray::read_ptr());
234
+ }
235
+
236
+ int64_t* write_ptr() {
237
+ return reinterpret_cast<int64_t*>(NArray::write_ptr());
238
+ }
239
+
240
+ private:
241
+ VALUE dtype() {
242
+ return numo_cInt64;
243
+ }
244
+ };
245
+
246
+ class UInt8: public NArray {
247
+ public:
248
+ UInt8(VALUE v) {
249
+ construct_value(this->dtype(), v);
250
+ }
251
+
252
+ UInt8(Rice::Object o) {
253
+ construct_value(this->dtype(), o.value());
254
+ }
255
+
256
+ UInt8(std::initializer_list<size_t> shape) {
257
+ construct_shape(this->dtype(), shape);
258
+ }
259
+
260
+ const uint8_t* read_ptr() {
261
+ return reinterpret_cast<const uint8_t*>(NArray::read_ptr());
262
+ }
263
+
264
+ uint8_t* write_ptr() {
265
+ return reinterpret_cast<uint8_t*>(NArray::write_ptr());
266
+ }
267
+
268
+ private:
269
+ VALUE dtype() {
270
+ return numo_cUInt8;
271
+ }
272
+ };
273
+
274
+ class UInt16: public NArray {
275
+ public:
276
+ UInt16(VALUE v) {
277
+ construct_value(this->dtype(), v);
278
+ }
279
+
280
+ UInt16(Rice::Object o) {
281
+ construct_value(this->dtype(), o.value());
282
+ }
283
+
284
+ UInt16(std::initializer_list<size_t> shape) {
285
+ construct_shape(this->dtype(), shape);
286
+ }
287
+
288
+ const uint16_t* read_ptr() {
289
+ return reinterpret_cast<const uint16_t*>(NArray::read_ptr());
290
+ }
291
+
292
+ uint16_t* write_ptr() {
293
+ return reinterpret_cast<uint16_t*>(NArray::write_ptr());
294
+ }
295
+
296
+ private:
297
+ VALUE dtype() {
298
+ return numo_cUInt16;
299
+ }
300
+ };
301
+
302
+ class UInt32: public NArray {
303
+ public:
304
+ UInt32(VALUE v) {
305
+ construct_value(this->dtype(), v);
306
+ }
307
+
308
+ UInt32(Rice::Object o) {
309
+ construct_value(this->dtype(), o.value());
310
+ }
311
+
312
+ UInt32(std::initializer_list<size_t> shape) {
313
+ construct_shape(this->dtype(), shape);
314
+ }
315
+
316
+ const uint32_t* read_ptr() {
317
+ return reinterpret_cast<const uint32_t*>(NArray::read_ptr());
318
+ }
319
+
320
+ uint32_t* write_ptr() {
321
+ return reinterpret_cast<uint32_t*>(NArray::write_ptr());
322
+ }
323
+
324
+ private:
325
+ VALUE dtype() {
326
+ return numo_cUInt32;
327
+ }
328
+ };
329
+
330
+ class UInt64: public NArray {
331
+ public:
332
+ UInt64(VALUE v) {
333
+ construct_value(this->dtype(), v);
334
+ }
335
+
336
+ UInt64(Rice::Object o) {
337
+ construct_value(this->dtype(), o.value());
338
+ }
339
+
340
+ UInt64(std::initializer_list<size_t> shape) {
341
+ construct_shape(this->dtype(), shape);
342
+ }
343
+
344
+ const uint64_t* read_ptr() {
345
+ return reinterpret_cast<const uint64_t*>(NArray::read_ptr());
346
+ }
347
+
348
+ uint64_t* write_ptr() {
349
+ return reinterpret_cast<uint64_t*>(NArray::write_ptr());
350
+ }
351
+
352
+ private:
353
+ VALUE dtype() {
354
+ return numo_cUInt64;
355
+ }
356
+ };
357
+
358
+ class SComplex: public NArray {
359
+ public:
360
+ SComplex(VALUE v) {
361
+ construct_value(this->dtype(), v);
362
+ }
363
+
364
+ SComplex(Rice::Object o) {
365
+ construct_value(this->dtype(), o.value());
366
+ }
367
+
368
+ SComplex(std::initializer_list<size_t> shape) {
369
+ construct_shape(this->dtype(), shape);
370
+ }
371
+
372
+ private:
373
+ VALUE dtype() {
374
+ return numo_cSComplex;
375
+ }
376
+ };
377
+
378
+ class DComplex: public NArray {
379
+ public:
380
+ DComplex(VALUE v) {
381
+ construct_value(this->dtype(), v);
382
+ }
383
+
384
+ DComplex(Rice::Object o) {
385
+ construct_value(this->dtype(), o.value());
386
+ }
387
+
388
+ DComplex(std::initializer_list<size_t> shape) {
389
+ construct_shape(this->dtype(), shape);
390
+ }
391
+
392
+ private:
393
+ VALUE dtype() {
394
+ return numo_cDComplex;
395
+ }
396
+ };
397
+
398
+ class Bit: public NArray {
399
+ public:
400
+ Bit(VALUE v) {
401
+ construct_value(this->dtype(), v);
402
+ }
403
+
404
+ Bit(Rice::Object o) {
405
+ construct_value(this->dtype(), o.value());
406
+ }
407
+
408
+ Bit(std::initializer_list<size_t> shape) {
409
+ construct_shape(this->dtype(), shape);
410
+ }
411
+
412
+ private:
413
+ VALUE dtype() {
414
+ return numo_cBit;
415
+ }
416
+ };
417
+
418
+ class RObject: public NArray {
419
+ public:
420
+ RObject(VALUE v) {
421
+ construct_value(this->dtype(), v);
422
+ }
423
+
424
+ RObject(Rice::Object o) {
425
+ construct_value(this->dtype(), o.value());
426
+ }
427
+
428
+ RObject(std::initializer_list<size_t> shape) {
429
+ construct_shape(this->dtype(), shape);
430
+ }
431
+
432
+ const VALUE* read_ptr() {
433
+ return reinterpret_cast<const VALUE*>(NArray::read_ptr());
434
+ }
435
+
436
+ VALUE* write_ptr() {
437
+ return reinterpret_cast<VALUE*>(NArray::write_ptr());
438
+ }
439
+
440
+ private:
441
+ VALUE dtype() {
442
+ return numo_cRObject;
443
+ }
444
+ };
445
+ }
446
+
447
+ namespace Rice::detail {
448
+ template<>
449
+ struct Type<numo::NArray>
450
+ {
451
+ static bool verify()
452
+ {
453
+ return true;
454
+ }
455
+ };
456
+
457
+ template<>
458
+ class From_Ruby<numo::NArray>
459
+ {
460
+ public:
461
+ numo::NArray convert(VALUE x)
462
+ {
463
+ return numo::NArray(x);
464
+ }
465
+ };
466
+
467
+ template<>
468
+ class To_Ruby<numo::NArray>
469
+ {
470
+ public:
471
+ VALUE convert(const numo::NArray& x) {
472
+ return x.value();
473
+ }
474
+ };
475
+
476
+ template<>
477
+ struct Type<numo::SFloat>
478
+ {
479
+ static bool verify()
480
+ {
481
+ return true;
482
+ }
483
+ };
484
+
485
+ template<>
486
+ class From_Ruby<numo::SFloat>
487
+ {
488
+ public:
489
+ numo::SFloat convert(VALUE x)
490
+ {
491
+ return numo::SFloat(x);
492
+ }
493
+ };
494
+
495
+ template<>
496
+ class To_Ruby<numo::SFloat>
497
+ {
498
+ public:
499
+ VALUE convert(const numo::SFloat& x) {
500
+ return x.value();
501
+ }
502
+ };
503
+
504
+ template<>
505
+ struct Type<numo::DFloat>
506
+ {
507
+ static bool verify()
508
+ {
509
+ return true;
510
+ }
511
+ };
512
+
513
+ template<>
514
+ class From_Ruby<numo::DFloat>
515
+ {
516
+ public:
517
+ numo::DFloat convert(VALUE x)
518
+ {
519
+ return numo::DFloat(x);
520
+ }
521
+ };
522
+
523
+ template<>
524
+ class To_Ruby<numo::DFloat>
525
+ {
526
+ public:
527
+ VALUE convert(const numo::DFloat& x) {
528
+ return x.value();
529
+ }
530
+ };
531
+
532
+ template<>
533
+ struct Type<numo::Int8>
534
+ {
535
+ static bool verify()
536
+ {
537
+ return true;
538
+ }
539
+ };
540
+
541
+ template<>
542
+ class From_Ruby<numo::Int8>
543
+ {
544
+ public:
545
+ numo::Int8 convert(VALUE x)
546
+ {
547
+ return numo::Int8(x);
548
+ }
549
+ };
550
+
551
+ template<>
552
+ class To_Ruby<numo::Int8>
553
+ {
554
+ public:
555
+ VALUE convert(const numo::Int8& x) {
556
+ return x.value();
557
+ }
558
+ };
559
+
560
+ template<>
561
+ struct Type<numo::Int16>
562
+ {
563
+ static bool verify()
564
+ {
565
+ return true;
566
+ }
567
+ };
568
+
569
+ template<>
570
+ class From_Ruby<numo::Int16>
571
+ {
572
+ public:
573
+ numo::Int16 convert(VALUE x)
574
+ {
575
+ return numo::Int16(x);
576
+ }
577
+ };
578
+
579
+ template<>
580
+ class To_Ruby<numo::Int16>
581
+ {
582
+ public:
583
+ VALUE convert(const numo::Int16& x) {
584
+ return x.value();
585
+ }
586
+ };
587
+
588
+ template<>
589
+ struct Type<numo::Int32>
590
+ {
591
+ static bool verify()
592
+ {
593
+ return true;
594
+ }
595
+ };
596
+
597
+ template<>
598
+ class From_Ruby<numo::Int32>
599
+ {
600
+ public:
601
+ numo::Int32 convert(VALUE x)
602
+ {
603
+ return numo::Int32(x);
604
+ }
605
+ };
606
+
607
+ template<>
608
+ class To_Ruby<numo::Int32>
609
+ {
610
+ public:
611
+ VALUE convert(const numo::Int32& x) {
612
+ return x.value();
613
+ }
614
+ };
615
+
616
+ template<>
617
+ struct Type<numo::Int64>
618
+ {
619
+ static bool verify()
620
+ {
621
+ return true;
622
+ }
623
+ };
624
+
625
+ template<>
626
+ class From_Ruby<numo::Int64>
627
+ {
628
+ public:
629
+ numo::Int64 convert(VALUE x)
630
+ {
631
+ return numo::Int64(x);
632
+ }
633
+ };
634
+
635
+ template<>
636
+ class To_Ruby<numo::Int64>
637
+ {
638
+ public:
639
+ VALUE convert(const numo::Int64& x) {
640
+ return x.value();
641
+ }
642
+ };
643
+
644
+ template<>
645
+ struct Type<numo::UInt8>
646
+ {
647
+ static bool verify()
648
+ {
649
+ return true;
650
+ }
651
+ };
652
+
653
+ template<>
654
+ class From_Ruby<numo::UInt8>
655
+ {
656
+ public:
657
+ numo::UInt8 convert(VALUE x)
658
+ {
659
+ return numo::UInt8(x);
660
+ }
661
+ };
662
+
663
+ template<>
664
+ class To_Ruby<numo::UInt8>
665
+ {
666
+ public:
667
+ VALUE convert(const numo::UInt8& x) {
668
+ return x.value();
669
+ }
670
+ };
671
+
672
+ template<>
673
+ struct Type<numo::UInt16>
674
+ {
675
+ static bool verify()
676
+ {
677
+ return true;
678
+ }
679
+ };
680
+
681
+ template<>
682
+ class From_Ruby<numo::UInt16>
683
+ {
684
+ public:
685
+ numo::UInt16 convert(VALUE x)
686
+ {
687
+ return numo::UInt16(x);
688
+ }
689
+ };
690
+
691
+ template<>
692
+ class To_Ruby<numo::UInt16>
693
+ {
694
+ public:
695
+ VALUE convert(const numo::UInt16& x) {
696
+ return x.value();
697
+ }
698
+ };
699
+
700
+ template<>
701
+ struct Type<numo::UInt32>
702
+ {
703
+ static bool verify()
704
+ {
705
+ return true;
706
+ }
707
+ };
708
+
709
+ template<>
710
+ class From_Ruby<numo::UInt32>
711
+ {
712
+ public:
713
+ numo::UInt32 convert(VALUE x)
714
+ {
715
+ return numo::UInt32(x);
716
+ }
717
+ };
718
+
719
+ template<>
720
+ class To_Ruby<numo::UInt32>
721
+ {
722
+ public:
723
+ VALUE convert(const numo::UInt32& x) {
724
+ return x.value();
725
+ }
726
+ };
727
+
728
+ template<>
729
+ struct Type<numo::UInt64>
730
+ {
731
+ static bool verify()
732
+ {
733
+ return true;
734
+ }
735
+ };
736
+
737
+ template<>
738
+ class From_Ruby<numo::UInt64>
739
+ {
740
+ public:
741
+ numo::UInt64 convert(VALUE x)
742
+ {
743
+ return numo::UInt64(x);
744
+ }
745
+ };
746
+
747
+ template<>
748
+ class To_Ruby<numo::UInt64>
749
+ {
750
+ public:
751
+ VALUE convert(const numo::UInt64& x) {
752
+ return x.value();
753
+ }
754
+ };
755
+
756
+ template<>
757
+ struct Type<numo::SComplex>
758
+ {
759
+ static bool verify()
760
+ {
761
+ return true;
762
+ }
763
+ };
764
+
765
+ template<>
766
+ class From_Ruby<numo::SComplex>
767
+ {
768
+ public:
769
+ numo::SComplex convert(VALUE x)
770
+ {
771
+ return numo::SComplex(x);
772
+ }
773
+ };
774
+
775
+ template<>
776
+ class To_Ruby<numo::SComplex>
777
+ {
778
+ public:
779
+ VALUE convert(const numo::SComplex& x) {
780
+ return x.value();
781
+ }
782
+ };
783
+
784
+ template<>
785
+ struct Type<numo::DComplex>
786
+ {
787
+ static bool verify()
788
+ {
789
+ return true;
790
+ }
791
+ };
792
+
793
+ template<>
794
+ class From_Ruby<numo::DComplex>
795
+ {
796
+ public:
797
+ numo::DComplex convert(VALUE x)
798
+ {
799
+ return numo::DComplex(x);
800
+ }
801
+ };
802
+
803
+ template<>
804
+ class To_Ruby<numo::DComplex>
805
+ {
806
+ public:
807
+ VALUE convert(const numo::DComplex& x) {
808
+ return x.value();
809
+ }
810
+ };
811
+
812
+ template<>
813
+ struct Type<numo::Bit>
814
+ {
815
+ static bool verify()
816
+ {
817
+ return true;
818
+ }
819
+ };
820
+
821
+ template<>
822
+ class From_Ruby<numo::Bit>
823
+ {
824
+ public:
825
+ numo::Bit convert(VALUE x)
826
+ {
827
+ return numo::Bit(x);
828
+ }
829
+ };
830
+
831
+ template<>
832
+ class To_Ruby<numo::Bit>
833
+ {
834
+ public:
835
+ VALUE convert(const numo::Bit& x) {
836
+ return x.value();
837
+ }
838
+ };
839
+
840
+ template<>
841
+ struct Type<numo::RObject>
842
+ {
843
+ static bool verify()
844
+ {
845
+ return true;
846
+ }
847
+ };
848
+
849
+ template<>
850
+ class From_Ruby<numo::RObject>
851
+ {
852
+ public:
853
+ numo::RObject convert(VALUE x)
854
+ {
855
+ return numo::RObject(x);
856
+ }
857
+ };
858
+
859
+ template<>
860
+ class To_Ruby<numo::RObject>
861
+ {
862
+ public:
863
+ VALUE convert(const numo::RObject& x) {
864
+ return x.value();
865
+ }
866
+ };
867
+ }