server_scripts 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3b272c99b33f7ecb954965b83b6a465c349721df
4
+ data.tar.gz: 8d9d49ee51086a521c8144f935348302bf13cfb7
5
+ SHA512:
6
+ metadata.gz: 7fe5a9cc5b3ad76c397a9dbb0d7223f40b7e679fd0203749e4aeae7cc4e9194129ed8cdabf5117538ba75075a292dd9a8d3d090700e8eded4f196c10779bc7da
7
+ data.tar.gz: e8ee6d52ccaf1c75c4404d656437bf8e32d1053cdb93945bd067af2b5bbcf584ea5cc61e50caf6312c7d91a35209f20473ebaad5b928aa3d31fedf3e993a712f
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # server-scripts
2
+
3
+ A gem providing easily usable server scripts for various supercomputers and servers.
4
+ The following functionality is provided:
5
+
6
+ * Generate job scripts and run batch jobs on TSUBAME 3.0, ABCI and reedbush machines.
7
+ * Parse various kinds of profiling files and generate meaningful output.
8
+
9
+ # Usage
10
+
11
+ ## ENV variables
12
+
13
+ Make sure the `SYSTEM` variable is set on your machine so that the gem will automatically
14
+ select the appropriate commands to run.
15
+
16
+ ## Writing job scripts
17
+
18
+ ### Simple openMPI job script
19
+
20
+ Use the `ServerScripts::BatchJob` class in your Ruby for outputting and submitting
21
+ job files. A simple MPI job can be generated and submitted as follows:
22
+
23
+ ``` ruby
24
+ require 'server_scripts'
25
+
26
+ include ServerScripts
27
+
28
+ task = BatchJob.new do |t|
29
+ t.nodes = 4
30
+ t.npernode = 4
31
+ t.wall_time = "1:30:00"
32
+ t.out_file = "out.log"
33
+ t.err_file = "err.log"
34
+ t.node_type = NodeType::FULL
35
+ t.mpi = OPENMPI
36
+ t.set_env "STARPU_SCHED", "dmda"
37
+ t.set_env "MKL_NUM_THREADS", "1"
38
+ t.executable = "a.out"
39
+ t.options = "3 32768 2048 2 2"
40
+ end
41
+
42
+ task.submit!
43
+ ```
44
+ This will generate a unique file name and submit it using the system's batch
45
+ job submission command.
46
+
47
+ ### Intel MPI profiling job script
48
+
49
+ If you want to generate traces using intel MPI, you can use additional options
50
+ like setting the ITAC and VTUNE output file/folder names.
51
+
52
+ ## Parse intel ITAC output
53
+
54
+ The intel ITAC tool can be helpful for generating traces of parallel MPI programs.
55
+ This class can be used for converting an ITAC file to an ideal trace and then generating
56
+ the function profile for obtaining things like the MPI wait time.
57
+
58
+ For extracting the MPI wait time from an ITAC trace, do the following:
59
+ ``` ruby
60
+ require 'server_scripts'
61
+
62
+ itac = ServerScripts::Parser::ITAC.new("itac_file.stf")
63
+ itac.generate_ideal_trace!
64
+
65
+ # All times are reported in seconds.
66
+
67
+ puts itac.mpi_time(kind: :ideal)
68
+ puts itac.mpi_time(kind: :real)
69
+ puts itac.event_time("getrf_start", how: :total, kind: :real)
70
+ puts itac.event_time("getrf_start", how: :per_proc, kind: :real)
71
+ ```
72
+
73
+ ## Parse starpu worker info
74
+
75
+
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'fileutils'
4
+ require 'server_scripts/version.rb'
5
+
6
+ gemspec = eval(IO.read("server_scripts.gemspec"))
7
+
8
+ Rake::TestTask.new(:test) do |t|
9
+ t.libs << "test"
10
+ t.libs << "lib"
11
+ t.test_files = FileList['test/**/test_*.rb']
12
+ end
@@ -0,0 +1,21 @@
1
+ module ServerScripts
2
+ module Computer
3
+ class ABCI < Base
4
+ FULL_NODE = "rt_F"
5
+
6
+ def header(node_type: FULL_NODE)
7
+ h = %q{
8
+ #!/bin/bash
9
+
10
+ #$ -cwd
11
+ #$ -l %{node_type}=%{nodes}
12
+ #$ -l h_rt=%{walltime}
13
+ #$ -N %{job_name}
14
+ #$ -o %{out_file}.log
15
+ #$ -e %{err_file}.log
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,30 @@
1
+ module ServerScripts
2
+ module Computer
3
+ class Base
4
+ def initialize(node_type, nodes, job_name, wall_time, out_file,
5
+ err_file, env)
6
+ @node_type = node_type
7
+ @nodes = nodes
8
+ @job_name = job_name
9
+ @wall_time = wall_time
10
+ @out_file = out_file
11
+ @err_file = err_file
12
+ @env = env
13
+ end
14
+
15
+ def node_type
16
+ if @node_type == NodeType::FULL
17
+ self.class::FULL_NODE
18
+ end
19
+ end
20
+
21
+ def env_setter
22
+ raise NotImplementedError
23
+ end
24
+
25
+ def job_submit_cmd
26
+ raise NotImplementedError
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,13 @@
1
+ module ServerScripts
2
+ module Computer
3
+ class SameerPC < Base
4
+ def initialize
5
+
6
+ end
7
+
8
+ def full_node
9
+ ""
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,36 @@
1
+ module ServerScripts
2
+ module Computer
3
+ class TSUBAME < Base
4
+ HEADER = %q{#!/bin/bash
5
+
6
+ #$ -cwd
7
+ #$ -l %{node_type}=%{nodes}
8
+ #$ -l h_rt=%{wall_time}
9
+ #$ -N %{job_name}
10
+ #$ -o %{out_file}.log
11
+ #$ -e %{err_file}.log
12
+ }
13
+
14
+ FULL_NODE = "f_node"
15
+
16
+ def header
17
+ HEADER % {node_type: node_type, nodes: @nodes, wall_time: @wall_time,
18
+ job_name: @job_name, out_file: @out_file, err_file: @err_file}
19
+ end
20
+
21
+ def env_setter
22
+ str = "\n"
23
+ @env.each do |var, value|
24
+ str += "export #{var}=#{value}\n"
25
+ end
26
+
27
+ str
28
+ end
29
+
30
+ def job_submit_cmd res_id: nil, batch_script:
31
+ res = res_id ? " -ar #{res_id} " : ""
32
+ "qsub -g #{ServeScripts.group_name} #{res} #{batch_script}"
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,5 @@
1
+ require 'server_scripts/computer/base'
2
+ require 'server_scripts/computer/tsubame'
3
+ require 'server_scripts/computer/abci'
4
+ require 'server_scripts/computer/sameer_pc'
5
+
@@ -0,0 +1,10 @@
1
+ module ServerScripts
2
+ module Executor
3
+ class Base
4
+ def run_cmd
5
+ raise NotImplementedError
6
+ end
7
+ end
8
+ end
9
+ end
10
+
@@ -0,0 +1,54 @@
1
+ # coding: utf-8
2
+ module ServerScripts
3
+ module Executor
4
+ class MPIProgram < Base
5
+ attr_reader :npernode
6
+ attr_reader :nprocs
7
+ attr_reader :env
8
+
9
+ def initialize(npernode: , nprocs:, env: {})
10
+ @npernode = npernode
11
+ @nprocs = nprocs
12
+ @env = env
13
+ end
14
+ end
15
+
16
+ class OpenMPI < MPIProgram
17
+ def run_cmd
18
+ "mpirun --mca mpi_cuda_support 0 #{env_variables} -N #{@npernode} -np #{@nprocs}"
19
+ end
20
+
21
+ private
22
+
23
+ def env_variables
24
+ str = ""
25
+ @env.each_key do |k|
26
+ str += " -x #{k} "
27
+ end
28
+
29
+ str
30
+ end
31
+ end
32
+
33
+ class IntelMPI < MPIProgram
34
+ attr_accessor :enable_itac
35
+ attr_accessor :vtune_fname
36
+
37
+ def initialize(*args)
38
+ super
39
+ @vtune_fname = "DEFAULT_VTUNE"
40
+ end
41
+
42
+ def run_cmd
43
+ hydra = @enable_itac ? "mpiexec.hydra -trace" : "mpiexec.hydra"
44
+ cmd = "#{hydra} -ppn #{@npernode} -np #{@nprocs} "
45
+ if @enable_itac
46
+ cmd += "amplxe-cl -trace-mpi –collect hpc-performance –r #{@vtune_fname} "
47
+ end
48
+
49
+ cmd
50
+ end
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,7 @@
1
+ module ServerScripts
2
+ module Executor
3
+ class Valgrind < Base
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module ServerScripts
2
+ module Executor
3
+ class Vanilla < Base
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ require 'server_scripts/executor/base'
2
+ require 'server_scripts/executor/mpi_program'
3
+ require 'server_scripts/executor/valgrind'
4
+ require 'server_scripts/executor/vanilla'
@@ -0,0 +1,6 @@
1
+ module ServerScripts
2
+ module NodeType
3
+ FULL = :full
4
+ HALF = :half
5
+ end
6
+ end # moduel ServerScripts
@@ -0,0 +1,3 @@
1
+ module ServerScripts
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,136 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'server_scripts/node_type'
3
+ require 'server_scripts/executor'
4
+ require 'server_scripts/computer'
5
+ require 'server_scripts/version'
6
+
7
+ module ServerScripts
8
+ class << self
9
+ def system
10
+ sys = ENV["SYSTEM"]
11
+
12
+ if sys == "SAMEER-PC"
13
+ ServerScripts::Computer::SameerPC
14
+ elsif sys == "TSUBAME"
15
+ ServerScripts::Computer::TSUBAME
16
+ elsif sys == "ABCI"
17
+ ServerScripts::Computer::ABCI
18
+ elsif sys == "REEDBUSH"
19
+ ServerScripts::Computer::REEDBUSH
20
+ end
21
+ end
22
+
23
+ def group_name
24
+ ENV["GROUP_NAME"]
25
+ end
26
+ end
27
+
28
+ class BatchJob
29
+ attr_accessor :job_name
30
+ attr_accessor :out_file
31
+ attr_accessor :err_file
32
+ attr_accessor :wall_time
33
+ attr_accessor :node_type
34
+ attr_accessor :options
35
+ attr_accessor :nodes
36
+ attr_accessor :npernode
37
+ attr_accessor :nprocs
38
+ attr_accessor :run_cmd, :executor, :executable
39
+ attr_accessor :additional_commands
40
+ attr_accessor :enable_intel_itac
41
+ attr_accessor :intel_vtune_fname
42
+
43
+ attr_reader :env
44
+ attr_reader :job_fname
45
+ attr_reader :system
46
+
47
+ def initialize job_fname
48
+ @job_fname = "sample_job_script.sh"
49
+ @job_name = "sample"
50
+ @out_file = "sample_out"
51
+ @err_file = "sample_err"
52
+ @wall_time = "1:00:00"
53
+ @node_type = NodeType::FULL
54
+ @nodes = 1
55
+ @npernode = 1
56
+ @nprocs = nil
57
+ @run_cmd = nil
58
+ @executor = :vanilla
59
+ @env = {}
60
+ @executable = "./a.out"
61
+ @job_script = ""
62
+ @enable_intel_itac = false
63
+ @additional_commands = []
64
+
65
+ yield self
66
+ end
67
+
68
+ def set_env var, value
69
+ raise ArgumentError, "Env #{var} is already set to #{value}." if @env[var]
70
+ @env[var] = value
71
+ end
72
+
73
+ def generate_job_script!
74
+ @system = ServerScripts.system.new(@node_type, @nodes, @job_name,
75
+ @wall_time, @out_file, @err_file, @env)
76
+ configure_executor!
77
+
78
+ @job_script += @system.header
79
+ @job_script += @system.env_setter
80
+ @additional_commands.each do |c|
81
+ @job_script += c + "\n"
82
+ end
83
+ @job_script += "#{@executor.run_cmd} #{@executable} #{@options}"
84
+ end
85
+
86
+ def submit!
87
+ generate_job_script! unless @job_script
88
+ File.write(@job_fname, @job_script)
89
+ # system(@system.job_submit_cmd(batch_script: @job_fname))
90
+ end
91
+
92
+ private
93
+
94
+ def configure_executor!
95
+ check_process_counts
96
+ @nprocs = @npernode * @nodes
97
+
98
+ if @executor == :openmpi
99
+ @executor = Executor::OpenMPI.new(npernode: @npernode, nprocs: @nprocs, env: @env)
100
+ elsif @executor == :intel
101
+ @executor = Executor::IntelMPI.new(npernode: @npernode, nprocs: @nprocs, env: @env)
102
+ @executor.enable_itac = !!@enable_intel_itac
103
+ @executor.vtune_fname = @intel_vtune_fname
104
+ elsif @executor == :vanilla
105
+ @executor = Executor::Vanilla.new
106
+ else
107
+ raise ArgumentError, "Cannot find MPI implementation #{@executor}."
108
+ end
109
+ end
110
+
111
+ def check_process_counts
112
+ if @nprocs && @nprocs != @npernode * @nodes
113
+ raise ArgumentError, "Number of processes should be #{@npernode * @nodes} not #{@nprocs}"
114
+ end
115
+ end
116
+ end
117
+
118
+ class Parser
119
+ class ITAC
120
+ attr_reader :ideal_trace_file, :real_trace_file
121
+
122
+ def initialize itac_file
123
+ @itac_file = itac_file
124
+ @ideal_trace_file = nil
125
+ @real_trace_file = nil
126
+ end
127
+
128
+ def generate_ideal_trace!
129
+
130
+ end
131
+ end # class ITAC
132
+ end # module Parser
133
+ end # module ServerScripts
134
+
135
+
136
+
@@ -0,0 +1,41 @@
1
+ #coding: utf-8
2
+ $:.unshift File.expand_path("../lib", __FILE__)
3
+
4
+ require 'server_scripts/version.rb'
5
+
6
+ def self.get_files
7
+ files = []
8
+ ['ext', 'lib', 'spec'].each do |folder|
9
+ files.concat Dir.glob "#{folder}/**/*"
10
+ end
11
+
12
+ files.concat(
13
+ ["Gemfile", "server_scripts.gemspec", "README.md", "Rakefile"])
14
+
15
+ files
16
+ end
17
+ files = get_files
18
+
19
+ ServerScripts::DESCRIPTION = <<MSG
20
+ Easily write scripts for submitted jobs to various machines.
21
+ MSG
22
+
23
+ Gem::Specification.new do |spec|
24
+ spec.name = 'server_scripts'
25
+ spec.version = ServerScripts::VERSION
26
+ spec.authors = ['Sameer Deshmukh']
27
+ spec.email = ['sameer.deshmukh93@gmail.com']
28
+ spec.summary = %q{Easily write scripts for submitted jobs to various machines.}
29
+ spec.description = ServerScripts::DESCRIPTION
30
+ spec.homepage = "https://github.com/v0dro/server-scripts"
31
+ spec.license = 'BSD-3 Clause'
32
+
33
+ spec.files = files
34
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
35
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
36
+ spec.require_paths = ["lib"]
37
+
38
+ spec.add_development_dependency 'minitest', '~> 5.11'
39
+ spec.add_development_dependency 'minitest-hooks'
40
+ spec.add_development_dependency 'minitest-fail-fast'
41
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: server_scripts
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sameer Deshmukh
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-01-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: minitest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest-hooks
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest-fail-fast
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: 'Easily write scripts for submitted jobs to various machines.
56
+
57
+ '
58
+ email:
59
+ - sameer.deshmukh93@gmail.com
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - Gemfile
65
+ - README.md
66
+ - Rakefile
67
+ - lib/server_scripts.rb
68
+ - lib/server_scripts/computer.rb
69
+ - lib/server_scripts/computer/abci.rb
70
+ - lib/server_scripts/computer/base.rb
71
+ - lib/server_scripts/computer/sameer_pc.rb
72
+ - lib/server_scripts/computer/tsubame.rb
73
+ - lib/server_scripts/executor.rb
74
+ - lib/server_scripts/executor/base.rb
75
+ - lib/server_scripts/executor/mpi_program.rb
76
+ - lib/server_scripts/executor/valgrind.rb
77
+ - lib/server_scripts/executor/vanilla.rb
78
+ - lib/server_scripts/node_type.rb
79
+ - lib/server_scripts/version.rb
80
+ - server_scripts.gemspec
81
+ homepage: https://github.com/v0dro/server-scripts
82
+ licenses:
83
+ - BSD-3 Clause
84
+ metadata: {}
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 2.6.14
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: Easily write scripts for submitted jobs to various machines.
105
+ test_files: []