server_scripts 0.0.1

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 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: []