ffi-fasttext 0.1.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2733c8705d35255f1f65e87fa0247da4d0f83a03
4
- data.tar.gz: e7e1917a8b172641441b039d147e1a9d83f217cc
3
+ metadata.gz: e68696e8ae484cfe2860a7c3d8b4d6ff82fa1634
4
+ data.tar.gz: 8d83b24e1d3a6f4088958e247576f27ecbf92075
5
5
  SHA512:
6
- metadata.gz: bc1eed1ab1a402a9b6541e1737626f01c630c08e6666a9f0d8505e02edc0e1178bda200eefc133fa0fb6201c88987ec6d860459cf51f979053ac28ef8a825c85
7
- data.tar.gz: a5fcd1bd377d33c4de336299a83ca7d06c7e93b2fcd51afa08363257776ea366e886cd0ea8faaf4ebd2c9964316e18f2be0c96d083f437a75d5dfe337f1c2519
6
+ metadata.gz: 2452d6825201de150eb467414551e847926407bbc29a92aaa560a3e59189ddee8747343cfd9429626147365e02522be8f1d4bda1133e2c2cc94fd04a3754c66c
7
+ data.tar.gz: e60d98a450292187fa566e5fe9a49a7534155440f20a9450bd9ce5364c6bd720c8e54422c38250b2a94d1832399ae0e977c3a0846c84c91e9e8451a045df973a
@@ -49,18 +49,19 @@ task :compile_fasttext do
49
49
  FASTTEXT_DIR = ::File.join(CWD, "..", "..", "..", "vendor", "fasttext")
50
50
 
51
51
  ::Dir.chdir(FASTTEXT_DIR) do
52
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c args.cc") unless ::File.exist?("args.o")
53
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c dictionary.cc") unless ::File.exist?("dictionary.o")
54
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c productquantizer.cc") unless ::File.exist?("productquantizer.o")
55
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c matrix.cc") unless ::File.exist?("matrix.o")
56
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c qmatrix.cc") unless ::File.exist?("qmatrix.o")
57
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c vector.cc") unless ::File.exist?("vector.o")
58
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c model.cc") unless ::File.exist?("model.o")
59
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c utils.cc") unless ::File.exist?("utils.o")
60
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c fasttext.cc") unless ::File.exist?("fasttext.o")
61
- sys("g++ -c -O3 -fPIC -pthread -std=c++0x -c ffi_fasttext.cc")
62
- sys("g++ -fPIC -pthread -std=c++0x args.o dictionary.o productquantizer.o matrix.o qmatrix.o vector.o model.o utils.o fasttext.o main.cc -o fasttext") unless ::File.exist?("fasttext")
63
- sys("g++ -fPIC -pthread -std=c++0x args.o dictionary.o productquantizer.o matrix.o qmatrix.o vector.o model.o utils.o fasttext.o ffi_fasttext.o -shared -o libfasttext.#{::FFI::Platform::LIBSUFFIX}")
52
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c args.cc") unless ::File.exist?("args.o")
53
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c dictionary.cc") unless ::File.exist?("dictionary.o")
54
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c productquantizer.cc") unless ::File.exist?("productquantizer.o")
55
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c matrix.cc") unless ::File.exist?("matrix.o")
56
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c qmatrix.cc") unless ::File.exist?("qmatrix.o")
57
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c vector.cc") unless ::File.exist?("vector.o")
58
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c model.cc") unless ::File.exist?("model.o")
59
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c utils.cc") unless ::File.exist?("utils.o")
60
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c fasttext.cc") unless ::File.exist?("fasttext.o")
61
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c ffi_fasttext.cc")
62
+ sys("g++ -c -O3 -fPIC -pthread -std=c++14 -c curlstream.cc")
63
+ sys("g++ -fPIC -pthread -std=c++14 args.o dictionary.o productquantizer.o matrix.o qmatrix.o vector.o model.o utils.o fasttext.o main.cc -o fasttext") unless ::File.exist?("fasttext")
64
+ sys("g++ -fPIC -pthread -std=c++14 args.o dictionary.o productquantizer.o matrix.o qmatrix.o vector.o model.o utils.o fasttext.o ffi_fasttext.o curlstream.o -lcurl -shared -o libfasttext.#{::FFI::Platform::LIBSUFFIX}")
64
65
  end
65
66
 
66
67
  unless ::File.exist?(::File.join(FASTTEXT_DIR, "libfasttext.#{::FFI::Platform::LIBSUFFIX}"))
@@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.add_dependency "ffi"
35
35
 
36
36
  spec.add_development_dependency "pry"
37
- spec.add_development_dependency "bundler", "~> 1.16"
38
- spec.add_development_dependency "rake", "~> 10.0"
39
- spec.add_development_dependency "minitest", "~> 5.0"
37
+ spec.add_development_dependency "bundler"
38
+ spec.add_development_dependency "rake"
39
+ spec.add_development_dependency "minitest"
40
40
  end
@@ -72,14 +72,15 @@ module FFI
72
72
  end
73
73
 
74
74
  attach_function :create, [:string], :pointer
75
+ attach_function :create_from_url, [:string], :pointer
75
76
  attach_function :destroy, [:pointer], :void
76
77
  attach_function :predict_string_free, [:pointer], :void
77
78
  attach_function :predict, [:pointer, :string, :int32_t], :strptr
78
79
 
79
80
  class Predictor
80
- def initialize(model_filename)
81
- raise "File does not exist" unless ::File.exist?(model_filename)
82
- @ptr = ::FFI::Fasttext.create(model_filename)
81
+ def initialize(model_name)
82
+ @ptr = ::File.exist?(model_name) ? ::FFI::Fasttext.create(model_name) : ::FFI::Fasttext.create_from_url(model_name)
83
+ raise "Error loading model" if @ptr.null?
83
84
  end
84
85
 
85
86
  def destroy!
@@ -1,5 +1,5 @@
1
1
  module FFI
2
2
  module Fasttext
3
- VERSION = "0.1.1"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
@@ -0,0 +1,132 @@
1
+ #include <memory>
2
+ #include <chrono>
3
+ #include <thread>
4
+ #include <streambuf>
5
+ #include "./curlstream.h"
6
+
7
+ class curl_global_initializer {
8
+ public:
9
+ curl_global_initializer() { curl_global_init(CURL_GLOBAL_DEFAULT); }
10
+ ~curl_global_initializer() { curl_global_cleanup(); }
11
+ };
12
+
13
+ namespace {
14
+ bool curl_initialized()
15
+ {
16
+ static std::unique_ptr<curl_global_initializer> initializer = std::make_unique<curl_global_initializer>();
17
+ return initializer != nullptr;
18
+ }
19
+ }
20
+
21
+ CurlStreambuff::CurlStreambuff(const std::string& url)
22
+ {
23
+ if (curl_initialized()) {
24
+ m_http_handle = curl_easy_init();
25
+ curl_easy_setopt(m_http_handle, CURLOPT_URL, url.c_str());
26
+ curl_easy_setopt(m_http_handle, CURLOPT_FOLLOWLOCATION, 1L);
27
+ curl_easy_setopt(m_http_handle, CURLOPT_SSL_VERIFYPEER, 0L);
28
+ curl_easy_setopt(m_http_handle, CURLOPT_WRITEFUNCTION, &CurlStreambuff::writer_callback);
29
+ curl_easy_setopt(m_http_handle, CURLOPT_WRITEDATA, this);
30
+
31
+ m_multi_handle = curl_multi_init();
32
+ curl_multi_add_handle(m_multi_handle, m_http_handle);
33
+ }
34
+ }
35
+
36
+ CurlStreambuff::~CurlStreambuff()
37
+ {
38
+ if (m_multi_handle && m_http_handle) {
39
+ curl_multi_remove_handle(m_multi_handle, m_http_handle);
40
+ }
41
+ if (m_http_handle) {
42
+ curl_easy_cleanup(m_http_handle);
43
+ }
44
+ if (m_multi_handle) {
45
+ curl_multi_cleanup(m_multi_handle);
46
+ }
47
+ }
48
+
49
+ std::streamsize CurlStreambuff::xsgetn(char *s, std::streamsize n)
50
+ {
51
+ auto remaining = n;
52
+ while (remaining > 0) {
53
+ if (m_pos >= m_size) {
54
+ if (fillbuffer() == 0) {
55
+ break;
56
+ }
57
+ }
58
+ auto to_copy = std::min<size_t>(remaining, m_size - m_pos);
59
+ memcpy(s, &m_buffer[m_pos], to_copy);
60
+ s += to_copy;
61
+ m_pos += to_copy;
62
+ remaining -= to_copy;
63
+ }
64
+ return n - remaining;
65
+ }
66
+
67
+ int CurlStreambuff::underflow()
68
+ {
69
+ if (m_pos >= m_size) {
70
+ if (fillbuffer() == 0) {
71
+ return traits_type::eof();
72
+ }
73
+ }
74
+ return traits_type::to_int_type(m_buffer[m_pos]);
75
+ }
76
+
77
+ int CurlStreambuff::uflow()
78
+ {
79
+ if (m_pos >= m_size) {
80
+ if (fillbuffer() == 0) {
81
+ return traits_type::eof();
82
+ }
83
+ }
84
+ return traits_type::to_int_type(m_buffer[m_pos++]);
85
+ }
86
+
87
+ int CurlStreambuff::writer_callback(char *data, size_t size, size_t count, void* ptr)
88
+ {
89
+ auto self = static_cast<CurlStreambuff*>(ptr);
90
+ auto bytes = size * count;
91
+ if(bytes > sizeof(m_buffer) || bytes == 0) {
92
+ return 0;
93
+ }
94
+ memcpy(&self->m_buffer[0], data, bytes);
95
+ self->m_size = bytes;
96
+ self->m_pos = 0;
97
+ return bytes;
98
+ }
99
+
100
+ size_t CurlStreambuff::fillbuffer()
101
+ {
102
+ using namespace std::chrono_literals;
103
+ m_size = 0;
104
+ int still_running_count = 1, repeats = 0;
105
+ while (still_running_count > 0) {
106
+ auto mc = curl_multi_perform(m_multi_handle, &still_running_count);
107
+ if (mc != CURLM_OK) {
108
+ return 0;
109
+ }
110
+ if (m_size > 0) {
111
+ break;
112
+ }
113
+ /* wait for activity, timeout or "nothing" */
114
+ int numfds;
115
+ mc = curl_multi_wait(m_multi_handle, nullptr, 0, 1000, &numfds);
116
+ if(mc != CURLM_OK) {
117
+ return 0;
118
+ }
119
+
120
+ /* 'numfds' being zero means either a timeout or no file descriptors to
121
+ wait for. Try timeout on first occurrence, then assume no file
122
+ descriptors and no file descriptors to wait for means wait for 100
123
+ milliseconds. */
124
+ if(numfds == 0) {
125
+ if (++repeats > 1) {
126
+ std::this_thread::sleep_for(100ms);
127
+ }
128
+ }
129
+ }
130
+ return m_size;
131
+ }
132
+
@@ -0,0 +1,39 @@
1
+ #include <iostream>
2
+ #include <streambuf>
3
+ #include <curl/curl.h>
4
+ #include <string.h>
5
+
6
+ class CurlStreambuff : public std::streambuf {
7
+ public:
8
+ explicit CurlStreambuff(const std::string& url);
9
+ ~CurlStreambuff();
10
+
11
+ // Copy and move prohibited
12
+ CurlStreambuff(const CurlStreambuff&) = delete;
13
+ CurlStreambuff& operator = (const CurlStreambuff&) = delete;
14
+ CurlStreambuff(CurlStreambuff && src) = delete;
15
+ CurlStreambuff& operator = (CurlStreambuff && rhs) = delete;
16
+
17
+ protected:
18
+ std::streamsize xsgetn(char *s, std::streamsize n) override;
19
+ int underflow() override;
20
+ int uflow() override;
21
+
22
+ private:
23
+ static int writer_callback(char *data, size_t size, size_t count, void* ptr);
24
+ size_t fillbuffer();
25
+
26
+ CURL *m_http_handle = nullptr;
27
+ CURLM *m_multi_handle = nullptr;
28
+ char m_buffer[CURL_MAX_WRITE_SIZE];
29
+ size_t m_pos = 0, m_size = 0;
30
+ };
31
+
32
+ class CurlStream : private CurlStreambuff, public std::istream {
33
+ public:
34
+ explicit CurlStream(const std::string& url)
35
+ : CurlStreambuff(url), std::istream(this)
36
+ {
37
+ }
38
+ };
39
+
@@ -43,8 +43,7 @@ void FastText::getVector(Vector& vec, const std::string& word) const {
43
43
  void FastText::saveVectors() {
44
44
  std::ofstream ofs(args_->output + ".vec");
45
45
  if (!ofs.is_open()) {
46
- std::cerr << "Error opening file for saving vectors." << std::endl;
47
- exit(EXIT_FAILURE);
46
+ throw std::runtime_error("Error opening file for saving vectors.");
48
47
  }
49
48
  ofs << dict_->nwords() << " " << args_->dim << std::endl;
50
49
  Vector vec(args_->dim);
@@ -59,8 +58,7 @@ void FastText::saveVectors() {
59
58
  void FastText::saveOutput() {
60
59
  std::ofstream ofs(args_->output + ".output");
61
60
  if (!ofs.is_open()) {
62
- std::cerr << "Error opening file for saving vectors." << std::endl;
63
- exit(EXIT_FAILURE);
61
+ throw std::runtime_error("Error opening file for saving vectors.");
64
62
  }
65
63
  if (quant_) {
66
64
  std::cerr << "Option -saveOutput is not supported for quantized models."
@@ -110,8 +108,7 @@ void FastText::saveModel() {
110
108
  }
111
109
  std::ofstream ofs(fn, std::ofstream::binary);
112
110
  if (!ofs.is_open()) {
113
- std::cerr << "Model file cannot be opened for saving!" << std::endl;
114
- exit(EXIT_FAILURE);
111
+ throw std::runtime_error("Model file cannot be opened for saving!");
115
112
  }
116
113
  signModel(ofs);
117
114
  args_->save(ofs);
@@ -137,18 +134,16 @@ void FastText::saveModel() {
137
134
  void FastText::loadModel(const std::string& filename) {
138
135
  std::ifstream ifs(filename, std::ifstream::binary);
139
136
  if (!ifs.is_open()) {
140
- std::cerr << "Model file cannot be opened for loading!" << std::endl;
141
- exit(EXIT_FAILURE);
142
- }
143
- if (!checkModel(ifs)) {
144
- std::cerr << "Model file has wrong file format!" << std::endl;
145
- exit(EXIT_FAILURE);
137
+ throw std::runtime_error("Model file cannot be opened for loading!");
146
138
  }
147
139
  loadModel(ifs);
148
140
  ifs.close();
149
141
  }
150
142
 
151
143
  void FastText::loadModel(std::istream& in) {
144
+ if (!checkModel(in)) {
145
+ throw std::runtime_error("Model file has wrong file format!");
146
+ }
152
147
  args_ = std::make_shared<Args>();
153
148
  dict_ = std::make_shared<Dictionary>(args_);
154
149
  input_ = std::make_shared<Matrix>();
@@ -172,10 +167,7 @@ void FastText::loadModel(std::istream& in) {
172
167
  }
173
168
 
174
169
  if (!quant_input && dict_->isPruned()) {
175
- std::cerr << "Invalid model file.\n"
176
- << "Please download the updated model from www.fasttext.cc.\n"
177
- << "See issue #332 on Github for more information.\n";
178
- exit(1);
170
+ throw std::runtime_error("Invalid model file");
179
171
  }
180
172
 
181
173
  in.read((char*) &args_->qout, sizeof(bool));
@@ -228,8 +220,7 @@ std::vector FastText::selectEmbeddings(int32_t cutoff) const {
228
220
 
229
221
  void FastText::quantize(std::shared_ptr<Args> qargs) {
230
222
  if (qargs->output.empty()) {
231
- std::cerr<<"No model provided!"<<std::endl;
232
- exit(1);
223
+ throw std::runtime_error("No model provided!");
233
224
  }
234
225
  loadModel(qargs->output + ".bin");
235
226
 
@@ -600,14 +591,11 @@ void FastText::loadVectors(std::string filename) {
600
591
  std::shared_ptr<Matrix> mat; // temp. matrix for pretrained vectors
601
592
  int64_t n, dim;
602
593
  if (!in.is_open()) {
603
- std::cerr << "Pretrained vectors file cannot be opened!" << std::endl;
604
- exit(EXIT_FAILURE);
594
+ throw std::runtime_error("Pretrained vectors file cannot be opened!");
605
595
  }
606
596
  in >> n >> dim;
607
597
  if (dim != args_->dim) {
608
- std::cerr << "Dimension of pretrained vectors does not match -dim option"
609
- << std::endl;
610
- exit(EXIT_FAILURE);
598
+ throw std::runtime_error("Dimension of pretrained vectors does not match -dim option");
611
599
  }
612
600
  mat = std::make_shared<Matrix>(n, dim);
613
601
  for (size_t i = 0; i < n; i++) {
@@ -639,13 +627,11 @@ void FastText::train(std::shared_ptr args) {
639
627
  dict_ = std::make_shared<Dictionary>(args_);
640
628
  if (args_->input == "-") {
641
629
  // manage expectations
642
- std::cerr << "Cannot use stdin for training!" << std::endl;
643
- exit(EXIT_FAILURE);
630
+ throw std::runtime_error("Cannot use stdin for training!");
644
631
  }
645
632
  std::ifstream ifs(args_->input);
646
633
  if (!ifs.is_open()) {
647
- std::cerr << "Input file cannot be opened!" << std::endl;
648
- exit(EXIT_FAILURE);
634
+ throw std::runtime_error("Input file cannot be opened!");
649
635
  }
650
636
  dict_->readFromFile(ifs);
651
637
  ifs.close();
@@ -8,6 +8,7 @@
8
8
 
9
9
  #include "real.h"
10
10
  #include "fasttext.h"
11
+ #include "curlstream.h"
11
12
 
12
13
  #ifdef __cplusplus
13
14
  #define EXTERN_C extern "C"
@@ -20,9 +21,27 @@
20
21
  #endif
21
22
 
22
23
  EXTERN_C_BEGIN
23
- fasttext::FastText* create(const char* model_name) {
24
+ fasttext::FastText* create(const char* model_filename) {
24
25
  fasttext::FastText* new_fasttext = new fasttext::FastText();
25
- new_fasttext->loadModel(std::string(model_name));
26
+ try {
27
+ new_fasttext->loadModel(model_filename);
28
+ } catch(std::exception&) {
29
+ delete new_fasttext;
30
+ return nullptr;
31
+ }
32
+
33
+ return new_fasttext;
34
+ }
35
+
36
+ fasttext::FastText* create_from_url(const char* model_url) {
37
+ fasttext::FastText* new_fasttext = new fasttext::FastText();
38
+ try {
39
+ CurlStream curlstream{model_url};
40
+ new_fasttext->loadModel(curlstream);
41
+ } catch(std::exception&) {
42
+ delete new_fasttext;
43
+ return nullptr;
44
+ }
26
45
 
27
46
  return new_fasttext;
28
47
  }
metadata CHANGED
@@ -1,85 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi-fasttext
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Dewitt
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-06-28 00:00:00.000000000 Z
11
+ date: 2020-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: ffi
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
18
  version: '0'
20
- type: :runtime
19
+ name: ffi
21
20
  prerelease: false
21
+ type: :runtime
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: pry
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - ">="
32
31
  - !ruby/object:Gem::Version
33
32
  version: '0'
34
- type: :development
33
+ name: pry
35
34
  prerelease: false
35
+ type: :development
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: bundler
43
42
  requirement: !ruby/object:Gem::Requirement
44
43
  requirements:
45
- - - "~>"
44
+ - - ">="
46
45
  - !ruby/object:Gem::Version
47
- version: '1.16'
48
- type: :development
46
+ version: '0'
47
+ name: bundler
49
48
  prerelease: false
49
+ type: :development
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '1.16'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rake
57
56
  requirement: !ruby/object:Gem::Requirement
58
57
  requirements:
59
- - - "~>"
58
+ - - ">="
60
59
  - !ruby/object:Gem::Version
61
- version: '10.0'
62
- type: :development
60
+ version: '0'
61
+ name: rake
63
62
  prerelease: false
63
+ type: :development
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '10.0'
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: minitest
71
70
  requirement: !ruby/object:Gem::Requirement
72
71
  requirements:
73
- - - "~>"
72
+ - - ">="
74
73
  - !ruby/object:Gem::Version
75
- version: '5.0'
76
- type: :development
74
+ version: '0'
75
+ name: minitest
77
76
  prerelease: false
77
+ type: :development
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '5.0'
82
+ version: '0'
83
83
  description: " FFI bindings for Facebook's FastText text classification library "
84
84
  email:
85
85
  - brandonsdewitt+rubygems@gmail.com
@@ -104,6 +104,8 @@ files:
104
104
  - vendor/fasttext/PATENTS
105
105
  - vendor/fasttext/args.cc
106
106
  - vendor/fasttext/args.h
107
+ - vendor/fasttext/curlstream.cc
108
+ - vendor/fasttext/curlstream.h
107
109
  - vendor/fasttext/dictionary.cc
108
110
  - vendor/fasttext/dictionary.h
109
111
  - vendor/fasttext/fasttext.cc
@@ -128,7 +130,7 @@ licenses:
128
130
  - MIT
129
131
  metadata:
130
132
  allowed_push_host: https://rubygems.org
131
- post_install_message:
133
+ post_install_message:
132
134
  rdoc_options: []
133
135
  require_paths:
134
136
  - lib
@@ -143,9 +145,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
143
145
  - !ruby/object:Gem::Version
144
146
  version: '0'
145
147
  requirements: []
146
- rubyforge_project:
147
- rubygems_version: 2.6.13
148
- signing_key:
148
+ rubyforge_project:
149
+ rubygems_version: 2.6.14.1
150
+ signing_key:
149
151
  specification_version: 4
150
152
  summary: FFI bindings for Facebook's FastText text classification library
151
153
  test_files: []