cnvrg 0.0.14 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/cnvrg.gemspec +9 -5
- data/lib/cnvrg.rb +0 -1
- data/lib/cnvrg/Images.rb +112 -26
- data/lib/cnvrg/api.rb +7 -4
- data/lib/cnvrg/cli.rb +2201 -455
- data/lib/cnvrg/data.rb +72 -0
- data/lib/cnvrg/datafiles.rb +509 -0
- data/lib/cnvrg/dataset.rb +296 -0
- data/lib/cnvrg/experiment.rb +19 -10
- data/lib/cnvrg/files.rb +302 -208
- data/lib/cnvrg/helpers.rb +42 -1
- data/lib/cnvrg/job.rb +0 -1
- data/lib/cnvrg/project.rb +55 -15
- data/lib/cnvrg/ssh.rb +95 -0
- data/lib/cnvrg/version.rb +2 -1
- metadata +48 -17
data/lib/cnvrg/helpers.rb
CHANGED
@@ -72,7 +72,7 @@ module Cnvrg
|
|
72
72
|
|
73
73
|
def cnvrgignore_content
|
74
74
|
%{
|
75
|
-
|
75
|
+
# cnvrg ignore: Ignore the following directories and files
|
76
76
|
# for example:
|
77
77
|
# some_dir/
|
78
78
|
# some_file.txt
|
@@ -81,6 +81,47 @@ module Cnvrg
|
|
81
81
|
}.strip
|
82
82
|
end
|
83
83
|
|
84
|
+
def hyper_content
|
85
|
+
%{# Hyperparameter Optimization is the process of choosing a set of parameters for a learning algorithm, usually with the goal of optimizing a measure of the algorithm's performance on an independent data set.
|
86
|
+
|
87
|
+
# Below is the list of parameters that will be used in the optimization process. Each parameter has a param_name that should match the argument that is feeded to the experiment s.t kernel => --kernel='rbf'
|
88
|
+
|
89
|
+
parameters:
|
90
|
+
# Integer parameter is a range of possible values between a minimum (inclusive)
|
91
|
+
# and maximum (not inclusive) values. Values are floored (0.7 => 0)
|
92
|
+
- param_name: "learning_rate"
|
93
|
+
type: "integer"
|
94
|
+
min: 0 # inclusive
|
95
|
+
max: 10 # not inclusive
|
96
|
+
scale: "linear"
|
97
|
+
steps: 4 # The number of linear steps to produce.
|
98
|
+
|
99
|
+
|
100
|
+
# Float parameter is a range of possible values between a minimum (inclusive)
|
101
|
+
# and maximum (not inclusive) values.
|
102
|
+
#
|
103
|
+
- param_name: "learning_rate"
|
104
|
+
type: "float" # precision is 9 after period
|
105
|
+
min: 0.00001
|
106
|
+
max: 0.1
|
107
|
+
scale: "log2" # Could be log10 as well
|
108
|
+
steps: 2
|
109
|
+
|
110
|
+
# Discrete parameter is an array of numerical values.
|
111
|
+
#
|
112
|
+
- param_name: "c"
|
113
|
+
type: "discrete"
|
114
|
+
values: [0, 0.1 ,0.001]
|
115
|
+
|
116
|
+
# Categorical parameter is an array of string values
|
117
|
+
#
|
118
|
+
- param_name: "kernel"
|
119
|
+
type: "categorical"
|
120
|
+
values: ["linear", "poly", "rbf"]
|
121
|
+
|
122
|
+
}
|
123
|
+
end
|
124
|
+
|
84
125
|
def readme_content
|
85
126
|
%{
|
86
127
|
# README
|
data/lib/cnvrg/job.rb
CHANGED
data/lib/cnvrg/project.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
module Cnvrg
|
3
3
|
class Project
|
4
|
-
attr_reader :slug, :owner, :title, :local_path
|
4
|
+
attr_reader :slug, :owner, :title, :local_path, :working_dir
|
5
5
|
|
6
6
|
RemoteURL ||= "https://cnvrg.io"
|
7
7
|
|
@@ -12,6 +12,7 @@ module Cnvrg
|
|
12
12
|
@title = config[:project_name]
|
13
13
|
@slug = config[:project_slug]
|
14
14
|
@owner = config[:owner]
|
15
|
+
@working_dir = project_home
|
15
16
|
rescue => e
|
16
17
|
end
|
17
18
|
|
@@ -23,18 +24,21 @@ module Cnvrg
|
|
23
24
|
return idx[:commit]
|
24
25
|
end
|
25
26
|
|
27
|
+
|
26
28
|
def url
|
27
29
|
url = Cnvrg::Helpers.remote_url
|
28
30
|
"#{url}/#{self.owner}/projects/#{self.slug}"
|
29
31
|
end
|
30
32
|
|
31
33
|
def update_ignore_list(new_ignore)
|
32
|
-
if new_ignore.empty?
|
34
|
+
if new_ignore.nil? or new_ignore.empty?
|
33
35
|
return true
|
34
36
|
end
|
37
|
+
list = new_ignore.split(",")
|
35
38
|
begin
|
36
39
|
File.open(self.local_path+"/.cnvrgignore", "a+") do |f|
|
37
|
-
|
40
|
+
f.puts("\n")
|
41
|
+
list.each do |i|
|
38
42
|
f.puts("#{i}\n")
|
39
43
|
end
|
40
44
|
end
|
@@ -48,13 +52,18 @@ module Cnvrg
|
|
48
52
|
ignore_list = []
|
49
53
|
File.open(self.local_path+"/.cnvrgignore", "r").each_line do |line|
|
50
54
|
line = line.strip
|
51
|
-
if line.start_with? "#"
|
55
|
+
if line.start_with? "#" or ignore_list.include? line or line.empty?
|
52
56
|
next
|
53
57
|
end
|
54
|
-
if line.end_with? "/"
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
+
if line.end_with? "/" or File.directory?(line)
|
59
|
+
if line.end_with? "/"
|
60
|
+
ignore_list << line.chop
|
61
|
+
else
|
62
|
+
ignore_list << line
|
63
|
+
end
|
64
|
+
all_sub = Dir.glob("#{line}/**/*", File::FNM_DOTMATCH).flatten
|
65
|
+
|
66
|
+
ignore_list << all_sub.flatten
|
58
67
|
else
|
59
68
|
ignore_list << line
|
60
69
|
end
|
@@ -71,7 +80,6 @@ module Cnvrg
|
|
71
80
|
else
|
72
81
|
|
73
82
|
list_dirs = [project_name,
|
74
|
-
project_name + "/data",
|
75
83
|
project_name + "/models",
|
76
84
|
project_name + "/notebooks",
|
77
85
|
project_name + "/src",
|
@@ -89,6 +97,7 @@ module Cnvrg
|
|
89
97
|
]
|
90
98
|
cnvrgreadme = Helpers.readme_content
|
91
99
|
cnvrgignore = Helpers.cnvrgignore_content
|
100
|
+
cnvrghyper = Helpers.hyper_content
|
92
101
|
|
93
102
|
begin
|
94
103
|
|
@@ -108,6 +117,8 @@ module Cnvrg
|
|
108
117
|
File.open(project_name + "/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
|
109
118
|
File.open(project_name + "/.cnvrgignore", "w+") { |f| f.write cnvrgignore }
|
110
119
|
File.open(project_name + "/README.md", "w+") { |f| f.write cnvrgreadme }
|
120
|
+
File.open(project_name + "/src/hyper.yaml", "w+") { |f| f.write cnvrghyper }
|
121
|
+
|
111
122
|
rescue
|
112
123
|
return false
|
113
124
|
end
|
@@ -136,14 +147,13 @@ module Cnvrg
|
|
136
147
|
FileUtils.mkdir_p list_dirs
|
137
148
|
FileUtils.touch list_files
|
138
149
|
File.open(".cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
|
139
|
-
File.open(".cnvrgignore", "w+") { |f| f.write cnvrgignore }
|
150
|
+
File.open(".cnvrgignore", "w+") { |f| f.write cnvrgignore } unless File.exist? ".cnvrgignore"
|
140
151
|
if !File.exist? "README" and !File.exist? "README.md"
|
141
152
|
FileUtils.touch [ "README.md" ]
|
142
153
|
File.open("README.md", "w+") { |f| f.write cnvrgreadme }
|
143
154
|
end
|
144
155
|
|
145
156
|
rescue => e
|
146
|
-
puts e
|
147
157
|
return false
|
148
158
|
end
|
149
159
|
return true
|
@@ -205,6 +215,26 @@ module Cnvrg
|
|
205
215
|
end
|
206
216
|
return true
|
207
217
|
end
|
218
|
+
def update_is_new_branch(new_branch)
|
219
|
+
config = YAML.load_file(@working_dir+"/.cnvrg/config.yml")
|
220
|
+
config[:new_branch] = new_branch
|
221
|
+
File.open(@working_dir+"/.cnvrg/config.yml", "w+") { |f| f.write config.to_yaml }
|
222
|
+
end
|
223
|
+
def get_new_branch
|
224
|
+
begin
|
225
|
+
config = YAML.load_file(@working_dir+"/.cnvrg/config.yml")
|
226
|
+
return config[:new_branch]
|
227
|
+
rescue =>e
|
228
|
+
return false
|
229
|
+
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def remove_new_branch
|
234
|
+
config = YAML.load_file(@working_dir+"/.cnvrg/config.yml")
|
235
|
+
new_config = config.except(:new_branch)
|
236
|
+
File.open(@working_dir+"/.cnvrg/config.yml", "w+") { |f| f.write new_config.to_yaml }
|
237
|
+
end
|
208
238
|
|
209
239
|
def generate_idx
|
210
240
|
if File.exists? "#{self.local_path}/.cnvrg/idx.yml"
|
@@ -219,15 +249,18 @@ module Cnvrg
|
|
219
249
|
list_ignore = self.get_ignore_list()
|
220
250
|
list.each do |e|
|
221
251
|
label = e.gsub(self.local_path + "/", "")
|
252
|
+
|
222
253
|
if File.directory? e
|
223
254
|
if list_ignore.include? label
|
224
255
|
next
|
225
256
|
end
|
257
|
+
|
226
258
|
tree_idx[label+"/"] = nil
|
227
259
|
else
|
228
260
|
if list_ignore.include? label
|
229
261
|
next
|
230
262
|
end
|
263
|
+
|
231
264
|
sha1 = Digest::SHA1.file(e).hexdigest
|
232
265
|
if old_idx.nil? or old_idx.to_h[:tree].nil?
|
233
266
|
tree_idx[label] = {sha1: sha1, commit_time: nil}
|
@@ -258,7 +291,7 @@ module Cnvrg
|
|
258
291
|
|
259
292
|
local_idx = self.generate_idx
|
260
293
|
response = Cnvrg::API.request("users/#{self.owner}/projects/#{self.slug}/status", 'POST', {idx: local_idx, new_branch: new_branch, current_commit: commit})
|
261
|
-
CLI.is_response_success(response)
|
294
|
+
CLI.is_response_success(response,false)
|
262
295
|
return response
|
263
296
|
end
|
264
297
|
|
@@ -267,7 +300,8 @@ module Cnvrg
|
|
267
300
|
commit = last_local_commit
|
268
301
|
end
|
269
302
|
response = Cnvrg::API.request("users/#{self.owner}/projects/#{self.slug}/commit/compare", 'POST', {current_commit: commit})
|
270
|
-
CLI.is_response_success(response)
|
303
|
+
CLI.is_response_success(response,false)
|
304
|
+
update_is_new_branch(response["result"]["new_branch"])
|
271
305
|
return response["result"]["new_branch"]
|
272
306
|
end
|
273
307
|
|
@@ -282,16 +316,22 @@ module Cnvrg
|
|
282
316
|
return true
|
283
317
|
end
|
284
318
|
|
285
|
-
def deploy(file_to_run, function, input_params, commit_to_run, instance_type, image_slug, scheduling_query, local_timestamp)
|
319
|
+
def deploy(file_to_run, function, input_params, commit_to_run, instance_type, image_slug, scheduling_query, local_timestamp,workers, file_input)
|
286
320
|
response = Cnvrg::API.request("users/#{@owner}/projects/#{@slug}/deploy", 'POST', {file_to_run: file_to_run, function: function,
|
287
321
|
image_slug: image_slug, input_params: input_params,
|
288
322
|
commit_sha1: commit_to_run,
|
289
323
|
instance_type: instance_type,
|
290
324
|
scheduling_query: scheduling_query,
|
291
|
-
local_timestamp: local_timestamp
|
325
|
+
local_timestamp: local_timestamp,
|
326
|
+
workers:workers,file_input:file_input})
|
292
327
|
return response
|
293
328
|
end
|
329
|
+
def list_commits
|
330
|
+
response = Cnvrg::API.request("users/#{self.owner}/projects/#{self.slug}/commits/list", 'GET')
|
331
|
+
CLI.is_response_success(response)
|
332
|
+
return response
|
294
333
|
|
334
|
+
end
|
295
335
|
def update_idx_with_commit!(commit)
|
296
336
|
idx_hash = YAML.load_file("#{self.local_path}/.cnvrg/idx.yml")
|
297
337
|
idx_hash[:commit] = commit
|
data/lib/cnvrg/ssh.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'cnvrg/files'
|
3
|
+
require 'docker'
|
4
|
+
require 'net/ssh'
|
5
|
+
|
6
|
+
|
7
|
+
module Cnvrg
|
8
|
+
class Ssh
|
9
|
+
attr_reader :is_ssh
|
10
|
+
|
11
|
+
|
12
|
+
def initialize(resp)
|
13
|
+
begin
|
14
|
+
@is_ssh = false
|
15
|
+
sts_path = resp["result"]["sts_path"]
|
16
|
+
|
17
|
+
uri = URI.parse(sts_path)
|
18
|
+
|
19
|
+
http_object = Net::HTTP.new(uri.host, uri.port)
|
20
|
+
http_object.use_ssl = true if uri.scheme == 'https'
|
21
|
+
request = Net::HTTP::Get.new(sts_path)
|
22
|
+
|
23
|
+
body = ""
|
24
|
+
http_object.start do |http|
|
25
|
+
response = http.request request
|
26
|
+
body = response.read_body
|
27
|
+
end
|
28
|
+
|
29
|
+
URLcrypt::key = [body].pack('H*')
|
30
|
+
ip = URLcrypt.decrypt(resp["result"]["machine_i"])
|
31
|
+
|
32
|
+
@user = URLcrypt.decrypt(resp["result"]["machine_u"])
|
33
|
+
key = URLcrypt.decrypt(resp["result"]["machine_k"])
|
34
|
+
@container = URLcrypt.decrypt(resp["result"]["machine_c"])
|
35
|
+
|
36
|
+
tempssh = Tempfile.new "sshkey"
|
37
|
+
tempssh.write open(key).read
|
38
|
+
tempssh.rewind
|
39
|
+
key_path = tempssh.path
|
40
|
+
count = 0
|
41
|
+
while count < 5
|
42
|
+
|
43
|
+
begin
|
44
|
+
@ssh = Net::SSH.start(ip, user=@user, :keys => key_path, :timeout => 10)
|
45
|
+
if !@ssh.nil?
|
46
|
+
@is_ssh = true
|
47
|
+
return
|
48
|
+
else
|
49
|
+
count+=1
|
50
|
+
sleep(2)
|
51
|
+
|
52
|
+
end
|
53
|
+
rescue
|
54
|
+
count+=1
|
55
|
+
sleep(2)
|
56
|
+
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
if tempssh
|
61
|
+
tempssh.close
|
62
|
+
tempssh.unlink
|
63
|
+
end
|
64
|
+
return false
|
65
|
+
rescue => e
|
66
|
+
|
67
|
+
puts e
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
def exec_command(command)
|
74
|
+
exec_command = "sudo -i -u #{@user} cnvrg exec_container #{@container} \"#{command}\" "
|
75
|
+
return @ssh.exec!(exec_command)
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
def close_ssh()
|
80
|
+
|
81
|
+
|
82
|
+
begin
|
83
|
+
|
84
|
+
@ssh.close
|
85
|
+
rescue => e
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
end
|
data/lib/cnvrg/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cnvrg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yochay Ettun
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-07-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -249,46 +249,74 @@ dependencies:
|
|
249
249
|
name: logstash-logger
|
250
250
|
requirement: !ruby/object:Gem::Requirement
|
251
251
|
requirements:
|
252
|
-
- - "
|
252
|
+
- - "~>"
|
253
253
|
- !ruby/object:Gem::Version
|
254
|
-
version:
|
254
|
+
version: 0.22.1
|
255
255
|
type: :runtime
|
256
256
|
prerelease: false
|
257
257
|
version_requirements: !ruby/object:Gem::Requirement
|
258
258
|
requirements:
|
259
|
-
- - "
|
259
|
+
- - "~>"
|
260
260
|
- !ruby/object:Gem::Version
|
261
|
-
version:
|
261
|
+
version: 0.22.1
|
262
262
|
- !ruby/object:Gem::Dependency
|
263
263
|
name: launchy
|
264
264
|
requirement: !ruby/object:Gem::Requirement
|
265
265
|
requirements:
|
266
|
-
- - "
|
266
|
+
- - "~>"
|
267
267
|
- !ruby/object:Gem::Version
|
268
|
-
version: '
|
268
|
+
version: '2.4'
|
269
269
|
type: :runtime
|
270
270
|
prerelease: false
|
271
271
|
version_requirements: !ruby/object:Gem::Requirement
|
272
272
|
requirements:
|
273
|
-
- - "
|
273
|
+
- - "~>"
|
274
274
|
- !ruby/object:Gem::Version
|
275
|
-
version: '
|
275
|
+
version: '2.4'
|
276
276
|
- !ruby/object:Gem::Dependency
|
277
277
|
name: docker-api
|
278
278
|
requirement: !ruby/object:Gem::Requirement
|
279
279
|
requirements:
|
280
|
-
- - "
|
280
|
+
- - "~>"
|
281
281
|
- !ruby/object:Gem::Version
|
282
|
-
version: '
|
282
|
+
version: '1.33'
|
283
283
|
type: :runtime
|
284
284
|
prerelease: false
|
285
285
|
version_requirements: !ruby/object:Gem::Requirement
|
286
286
|
requirements:
|
287
|
-
- - "
|
287
|
+
- - "~>"
|
288
288
|
- !ruby/object:Gem::Version
|
289
|
-
version: '
|
289
|
+
version: '1.33'
|
290
290
|
- !ruby/object:Gem::Dependency
|
291
291
|
name: rubyzip
|
292
|
+
requirement: !ruby/object:Gem::Requirement
|
293
|
+
requirements:
|
294
|
+
- - "~>"
|
295
|
+
- !ruby/object:Gem::Version
|
296
|
+
version: '1.2'
|
297
|
+
type: :runtime
|
298
|
+
prerelease: false
|
299
|
+
version_requirements: !ruby/object:Gem::Requirement
|
300
|
+
requirements:
|
301
|
+
- - "~>"
|
302
|
+
- !ruby/object:Gem::Version
|
303
|
+
version: '1.2'
|
304
|
+
- !ruby/object:Gem::Dependency
|
305
|
+
name: activesupport
|
306
|
+
requirement: !ruby/object:Gem::Requirement
|
307
|
+
requirements:
|
308
|
+
- - "~>"
|
309
|
+
- !ruby/object:Gem::Version
|
310
|
+
version: '5.0'
|
311
|
+
type: :runtime
|
312
|
+
prerelease: false
|
313
|
+
version_requirements: !ruby/object:Gem::Requirement
|
314
|
+
requirements:
|
315
|
+
- - "~>"
|
316
|
+
- !ruby/object:Gem::Version
|
317
|
+
version: '5.0'
|
318
|
+
- !ruby/object:Gem::Dependency
|
319
|
+
name: ruby-progressbar
|
292
320
|
requirement: !ruby/object:Gem::Requirement
|
293
321
|
requirements:
|
294
322
|
- - ">="
|
@@ -302,7 +330,7 @@ dependencies:
|
|
302
330
|
- !ruby/object:Gem::Version
|
303
331
|
version: '0'
|
304
332
|
- !ruby/object:Gem::Dependency
|
305
|
-
name:
|
333
|
+
name: net-ssh
|
306
334
|
requirement: !ruby/object:Gem::Requirement
|
307
335
|
requirements:
|
308
336
|
- - ">="
|
@@ -330,12 +358,16 @@ files:
|
|
330
358
|
- lib/cnvrg/api.rb
|
331
359
|
- lib/cnvrg/auth.rb
|
332
360
|
- lib/cnvrg/cli.rb
|
361
|
+
- lib/cnvrg/data.rb
|
362
|
+
- lib/cnvrg/datafiles.rb
|
363
|
+
- lib/cnvrg/dataset.rb
|
333
364
|
- lib/cnvrg/experiment.rb
|
334
365
|
- lib/cnvrg/files.rb
|
335
366
|
- lib/cnvrg/helpers.rb
|
336
367
|
- lib/cnvrg/job.rb
|
337
368
|
- lib/cnvrg/project.rb
|
338
369
|
- lib/cnvrg/runner.rb
|
370
|
+
- lib/cnvrg/ssh.rb
|
339
371
|
- lib/cnvrg/version.rb
|
340
372
|
homepage: https://cnvrg.io
|
341
373
|
licenses: []
|
@@ -356,9 +388,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
356
388
|
version: '0'
|
357
389
|
requirements: []
|
358
390
|
rubyforge_project:
|
359
|
-
rubygems_version: 2.
|
391
|
+
rubygems_version: 2.6.12
|
360
392
|
signing_key:
|
361
393
|
specification_version: 4
|
362
394
|
summary: A CLI tool for interacting with cnvrg.io.
|
363
395
|
test_files: []
|
364
|
-
has_rdoc:
|