bio-gemma-wrapper 0.99.3 → 0.99.4
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 +4 -4
- data/VERSION +1 -1
- data/bin/gemma-wrapper +22 -9
- data/gemma-wrapper.gemspec +1 -0
- data/lib/lock.rb +95 -0
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: da5f26b8acd9c3782c2b3f5f2a39af965fc7e1785cc820b49faca82924d74e51
|
|
4
|
+
data.tar.gz: 17035ee5fada269ae88dd0ed91d84075b2af88b400de1d0e9829cbdb60d5d0cb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eaec3c7dad4fc1bda713765e056bfe11dd69d4ca850333fed5a1a27e344724365a705ddf7845ce63b5af6b35ab6140da10f4bc7067aaa4539e47f6c6f94de1f0
|
|
7
|
+
data.tar.gz: c26b282c0fd7c70a702467e58c3f6ea22f820d91a8a364b335cdab7e807add9cf1079faa25c46a87b89c78e4293990cdea2210427c5f9c3565bd5040fdbef496
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.99.
|
|
1
|
+
0.99.4
|
data/bin/gemma-wrapper
CHANGED
|
@@ -71,6 +71,8 @@ require 'optparse'
|
|
|
71
71
|
require 'tempfile'
|
|
72
72
|
require 'tmpdir'
|
|
73
73
|
|
|
74
|
+
require 'lock'
|
|
75
|
+
|
|
74
76
|
split_at = ARGV.index('--')
|
|
75
77
|
|
|
76
78
|
if split_at
|
|
@@ -194,6 +196,7 @@ warning = lambda do |*msg|
|
|
|
194
196
|
record[:warnings].push *msg.join("")
|
|
195
197
|
OUTPUT.print "WARNING: ",*msg,"\n"
|
|
196
198
|
end
|
|
199
|
+
|
|
197
200
|
info = lambda do |*msg|
|
|
198
201
|
record[:debug].push *msg.join("") if options[:json] and options[:debug]
|
|
199
202
|
OUTPUT.print *msg,"\n" if !options[:quiet]
|
|
@@ -215,14 +218,14 @@ GEMMA_K_BANNER = "gemma-wrapper #{version} (Ruby #{RUBY_VERSION}) by Pjotr Prins
|
|
|
215
218
|
info.call GEMMA_K_BANNER
|
|
216
219
|
|
|
217
220
|
# Check gemma version
|
|
218
|
-
GEMMA_COMMAND=options[:gemma_command]
|
|
219
|
-
info.call "NOTE: gemma-wrapper is soon to be replaced by gemma2/lib"
|
|
220
|
-
|
|
221
221
|
begin
|
|
222
|
-
|
|
222
|
+
gemma_command2 = options[:gemma_command]
|
|
223
|
+
info.call "NOTE: gemma-wrapper is soon to be replaced by gemma2/lib"
|
|
224
|
+
|
|
225
|
+
GEMMA_INFO = `#{gemma_command2}`
|
|
223
226
|
rescue Errno::ENOENT
|
|
224
|
-
|
|
225
|
-
error.call "<#{
|
|
227
|
+
gemma_command2 = "gemma"
|
|
228
|
+
error.call "<#{gemma_command2}> command not found"
|
|
226
229
|
end
|
|
227
230
|
|
|
228
231
|
gemma_version_header = GEMMA_INFO.split("\n").grep(/GEMMA|Version/)[0].strip
|
|
@@ -329,6 +332,14 @@ end
|
|
|
329
332
|
HASH = compute_hash.call()
|
|
330
333
|
options[:hash] = HASH
|
|
331
334
|
|
|
335
|
+
at_exit do
|
|
336
|
+
Lock.release(HASH)
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
Lock.create(HASH) # this will wait for a lock to expire
|
|
340
|
+
|
|
341
|
+
joblog = options[:cache_dir]+"/"+HASH+"-parallel.log"
|
|
342
|
+
|
|
332
343
|
# Create cache dir
|
|
333
344
|
FileUtils::mkdir_p options[:cache_dir]
|
|
334
345
|
|
|
@@ -352,7 +363,7 @@ hashme =
|
|
|
352
363
|
debug.call "Options: ",options,"\n" if !options[:quiet]
|
|
353
364
|
|
|
354
365
|
invoke_gemma = lambda do |extra_args, cache_hit = false, chr = "full", permutation = 1|
|
|
355
|
-
cmd = "#{
|
|
366
|
+
cmd = "#{gemma_command2} #{GEMMA_ARGS.join(' ')} #{extra_args.join(' ')}"
|
|
356
367
|
record[:gemma_command] = cmd
|
|
357
368
|
return if cache_hit
|
|
358
369
|
if options[:slurm]
|
|
@@ -552,15 +563,17 @@ if options[:parallel]
|
|
|
552
563
|
cmd = parallel_cmds.join("\\n")
|
|
553
564
|
|
|
554
565
|
cmd = "echo -e \"#{cmd}\""
|
|
555
|
-
err = execute.call(cmd+"|parallel") # all jobs in parallel
|
|
566
|
+
err = execute.call(cmd+"|parallel --joblog #{joblog}") # first try optimistically to run all jobs in parallel
|
|
556
567
|
if err != 0
|
|
557
568
|
[16,8,4,1].each do |jobs|
|
|
558
569
|
info.call("Failed to complete parallel run -- retrying with smaller RAM footprint!")
|
|
559
|
-
err = execute.call(cmd+"|parallel -j #{jobs}")
|
|
570
|
+
err = execute.call(cmd+"|parallel -j #{jobs} --resume --joblog #{joblog}")
|
|
560
571
|
break if err == 0
|
|
561
572
|
end
|
|
562
573
|
if err != 0
|
|
563
574
|
info.call("Run failed!")
|
|
575
|
+
# Remove remaining files
|
|
576
|
+
FileUtils.rm_rf("#{tmpdir}/*", secure: true)
|
|
564
577
|
exit err
|
|
565
578
|
end
|
|
566
579
|
end
|
data/gemma-wrapper.gemspec
CHANGED
data/lib/lock.rb
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Locking module for gemma (wrapper)
|
|
2
|
+
#
|
|
3
|
+
|
|
4
|
+
=begin
|
|
5
|
+
|
|
6
|
+
The logic is as follows:
|
|
7
|
+
|
|
8
|
+
1. a program creates a named lock file (based on a hash of its inputs) with its PID
|
|
9
|
+
2. on exit it destroys the file
|
|
10
|
+
3. a new program checks for the lock file
|
|
11
|
+
4. if it exists and the PID is still in the ps table - wait
|
|
12
|
+
5. when the pid disappears or the lock file - continue
|
|
13
|
+
6. a timeout will return an error in 3 minutes
|
|
14
|
+
|
|
15
|
+
Note that there is a theoretical chance the lock file existed, but disappeared. I think I have it covered by ignoring the unlink errors. Also the use of /proc/PID is Linux specific.
|
|
16
|
+
|
|
17
|
+
=end
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
require 'timeout'
|
|
21
|
+
|
|
22
|
+
module Lock
|
|
23
|
+
|
|
24
|
+
def self.local name
|
|
25
|
+
ENV['HOME']+"/."+name.gsub("/","-")+".lck"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.lock_pid name
|
|
29
|
+
lockfn = local(name)
|
|
30
|
+
if File.exist?(lockfn)
|
|
31
|
+
File.read(lockfn).to_i
|
|
32
|
+
else
|
|
33
|
+
0
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.locked? name
|
|
38
|
+
lockfn = local(name)
|
|
39
|
+
pid = lock_pid(name)
|
|
40
|
+
if File.exist?("/proc/#{pid}")
|
|
41
|
+
true
|
|
42
|
+
else
|
|
43
|
+
# the program went away - remove any 'stale' lock
|
|
44
|
+
begin
|
|
45
|
+
File.unlink(lockfn)
|
|
46
|
+
rescue Errno::ENOENT
|
|
47
|
+
# ignore error when the lock file went missing
|
|
48
|
+
end
|
|
49
|
+
false # --> no longer locked
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def Lock::create name
|
|
54
|
+
wait_for(name)
|
|
55
|
+
lockfn = local(name)
|
|
56
|
+
if File.exist?(lockfn)
|
|
57
|
+
$stderr.print "\nERROR: Can not steal #{lockfn}"
|
|
58
|
+
exit 1
|
|
59
|
+
end
|
|
60
|
+
File.open(lockfn, File::RDWR|File::CREAT, 0644) do |f|
|
|
61
|
+
f.flock(File::LOCK_EX)
|
|
62
|
+
f.print(Process.pid)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def Lock::wait_for name
|
|
67
|
+
lockfn = local(name)
|
|
68
|
+
begin
|
|
69
|
+
status = Timeout::timeout(180) { # 3 minutes
|
|
70
|
+
while locked?(name)
|
|
71
|
+
$stderr.print("\nWaiting for lock #{lockfn}...")
|
|
72
|
+
sleep 2
|
|
73
|
+
end
|
|
74
|
+
}
|
|
75
|
+
rescue Timeout::Error
|
|
76
|
+
$stderr.print "\nERROR: Timed out, but I can not steal #{lockfn}"
|
|
77
|
+
exit 1
|
|
78
|
+
end
|
|
79
|
+
# yah! lock is released
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def Lock::release name
|
|
83
|
+
lockfn = local(name)
|
|
84
|
+
if Process.pid == lock_pid(name)
|
|
85
|
+
begin
|
|
86
|
+
File.unlink(lockfn) # PID expired
|
|
87
|
+
rescue Errno::ENOENT
|
|
88
|
+
# ignore error when the lock file went missing
|
|
89
|
+
end
|
|
90
|
+
else
|
|
91
|
+
$stderr.print "\nERROR: can not release #{lockfn} because it is not owned by me"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bio-gemma-wrapper
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.99.
|
|
4
|
+
version: 0.99.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Pjotr Prins
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-11-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: GEMMA wrapper adds LOCO and permutation support. Also runs in parallel
|
|
14
14
|
and caches K between runs with LOCO support
|
|
@@ -24,6 +24,7 @@ files:
|
|
|
24
24
|
- VERSION
|
|
25
25
|
- bin/gemma-wrapper
|
|
26
26
|
- gemma-wrapper.gemspec
|
|
27
|
+
- lib/lock.rb
|
|
27
28
|
homepage: https://github.com/genetics-statistics/gemma-wrapper
|
|
28
29
|
licenses:
|
|
29
30
|
- GPL3
|
|
@@ -43,7 +44,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
43
44
|
- !ruby/object:Gem::Version
|
|
44
45
|
version: '0'
|
|
45
46
|
requirements: []
|
|
46
|
-
rubygems_version: 3.
|
|
47
|
+
rubygems_version: 3.1.4
|
|
47
48
|
signing_key:
|
|
48
49
|
specification_version: 4
|
|
49
50
|
summary: GEMMA with LOCO and permutations
|