From 896048efbcbe09b05aeb8b36dd6a7870921e544b Mon Sep 17 00:00:00 2001 From: Ole Tange Date: Sat, 14 Jul 2018 06:11:58 +0200 Subject: [PATCH] parallel: Calculate #CPU as either #threads, #cores, or #sockets. --- src/parallel | 825 ++++++++++--------- src/parallel.pod | 160 ++-- src/parallel_design.pod | 48 +- testsuite/tests-to-run/parallel-polarhome.sh | 24 +- testsuite/wanted-results/parallel-polarhome | 171 +++- 5 files changed, 730 insertions(+), 498 deletions(-) diff --git a/src/parallel b/src/parallel index cedc56f9..55dcff5e 100755 --- a/src/parallel +++ b/src/parallel @@ -991,7 +991,11 @@ sub options_hash { "noswap" => \$opt::noswap, "max-line-length-allowed" => \$opt::max_line_length_allowed, "number-of-cpus" => \$opt::number_of_cpus, + "number-of-sockets" => \$opt::number_of_sockets, "number-of-cores" => \$opt::number_of_cores, + "number-of-threads" => \$opt::number_of_threads, + "use-sockets-instead-of-threads" => \$opt::use_sockets_instead_of_threads, + "use-cores-instead-of-threads" => \$opt::use_cores_instead_of_threads, "use-cpus-instead-of-cores" => \$opt::use_cpus_instead_of_cores, "shellquote|shell_quote|shell-quote" => \$opt::shellquote, "nice=i" => \$opt::nice, @@ -1215,12 +1219,18 @@ sub parse_options { if(defined $opt::arg_file_sep) { $Global::arg_file_sep = $opt::arg_file_sep; } + if(defined $opt::number_of_sockets) { + print SSHLogin::no_of_sockets(),"\n"; wait_and_exit(0); + } if(defined $opt::number_of_cpus) { - print SSHLogin::no_of_cpus(),"\n"; wait_and_exit(0); + print SSHLogin::no_of_cores(),"\n"; wait_and_exit(0); } if(defined $opt::number_of_cores) { print SSHLogin::no_of_cores(),"\n"; wait_and_exit(0); } + if(defined $opt::number_of_threads) { + print SSHLogin::no_of_threads(),"\n"; wait_and_exit(0); + } if(defined $opt::max_line_length_allowed) { print Limits::Command::real_max_length(),"\n"; wait_and_exit(0); } @@ -3547,12 +3557,14 @@ sub filter_hosts { # Uses: # %Global::host # $Global::minimal_command_line_length + # $opt::use_sockets_instead_of_threads + # $opt::use_cores_instead_of_threads # $opt::use_cpus_instead_of_cores # Returns: N/A - my ($ncores_ref, $ncpus_ref, $time_to_login_ref, $maxlen_ref, - $echo_ref, $down_hosts_ref) = - parse_host_filtering(parallelized_host_filtering()); + my ($nsockets_ref,$ncores_ref, $nthreads_ref, $time_to_login_ref, + $maxlen_ref, $echo_ref, $down_hosts_ref) = + parse_host_filtering(parallelized_host_filtering()); delete @Global::host{@$down_hosts_ref}; @$down_hosts_ref and ::warning("Removed @$down_hosts_ref."); @@ -3560,17 +3572,22 @@ sub filter_hosts { $Global::minimal_command_line_length = 8_000_000; while (my ($sshlogin, $obj) = each %Global::host) { if($sshlogin eq ":") { next } - $ncpus_ref->{$sshlogin} or - ::die_bug("ncpus missing: ".$obj->serverlogin()); + $nsockets_ref->{$sshlogin} or + ::die_bug("nsockets missing: ".$obj->serverlogin()); $ncores_ref->{$sshlogin} or ::die_bug("ncores missing: ".$obj->serverlogin()); + $nthreads_ref->{$sshlogin} or + ::die_bug("nthreads missing: ".$obj->serverlogin()); $time_to_login_ref->{$sshlogin} or ::die_bug("time_to_login missing: ".$obj->serverlogin()); $maxlen_ref->{$sshlogin} or ::die_bug("maxlen missing: ".$obj->serverlogin()); + $obj->set_ncpus($nthreads_ref->{$sshlogin}); if($opt::use_cpus_instead_of_cores) { - $obj->set_ncpus($ncpus_ref->{$sshlogin}); - } else { + $obj->set_ncpus($ncores_ref->{$sshlogin}); + } elsif($opt::use_sockets_instead_of_threads) { + $obj->set_ncpus($nsockets_ref->{$sshlogin}); + } elsif($opt::use_cores_instead_of_threads) { $obj->set_ncpus($ncores_ref->{$sshlogin}); } $obj->set_time_to_login($time_to_login_ref->{$sshlogin}); @@ -3579,8 +3596,9 @@ sub filter_hosts { ::min($Global::minimal_command_line_length, int($maxlen_ref->{$sshlogin}/2)); ::debug("init", "Timing from -S:$sshlogin ", - " ncpus:",$ncpus_ref->{$sshlogin}, + " nsockets:",$nsockets_ref->{$sshlogin}, " ncores:", $ncores_ref->{$sshlogin}, + " nthreads:",$nthreads_ref->{$sshlogin}, " time_to_login:", $time_to_login_ref->{$sshlogin}, " maxlen:", $maxlen_ref->{$sshlogin}, " min_max_len:", $Global::minimal_command_line_length,"\n"); @@ -3591,14 +3609,16 @@ sub parse_host_filtering { # Input: # @lines = output from parallelized_host_filtering() # Returns: + # \%nsockets = number of sockets of {host} # \%ncores = number of cores of {host} - # \%ncpus = number of cpus of {host} + # \%nthreads = number of hyperthreaded cores of {host} # \%time_to_login = time_to_login on {host} # \%maxlen = max command len on {host} # \%echo = echo received from {host} # \@down_hosts = list of hosts with no answer local $/ = "\n"; - my (%ncores, %ncpus, %time_to_login, %maxlen, %echo, @down_hosts); + my (%nsockets, %ncores, %nthreads, %time_to_login, %maxlen, %echo, + @down_hosts); for (@_) { ::debug("init",$_); chomp; @@ -3629,11 +3649,12 @@ sub parse_host_filtering { push(@down_hosts, $host); } elsif($col[6] eq "127") { # signal == 127: parallel not installed remote - # Set ncpus and ncores = 1 + # Set nsockets, ncores, nthreads = 1 ::warning("Could not figure out ". "number of cpus on $host. Using 1."); + $nsockets{$host} = 1; $ncores{$host} = 1; - $ncpus{$host} = 1; + $nthreads{$host} = 1; $maxlen{$host} = Limits::Command::max_length(); } elsif($col[0] =~ /^\d+$/ and $Global::host{$host}) { # Remember how log it took to log in @@ -3651,10 +3672,12 @@ sub parse_host_filtering { if(/parallel: Warning: Cannot figure out number of/) { next; } - if(not $ncores{$col[0]}) { + if(not $nsockets{$col[0]}) { + $nsockets{$col[0]} = $col[1]; + } elsif(not $ncores{$col[0]}) { $ncores{$col[0]} = $col[1]; - } elsif(not $ncpus{$col[0]}) { - $ncpus{$col[0]} = $col[1]; + } elsif(not $nthreads{$col[0]}) { + $nthreads{$col[0]} = $col[1]; } elsif(not $maxlen{$col[0]}) { $maxlen{$col[0]} = $col[1]; } elsif(not $echo{$col[0]}) { @@ -3676,7 +3699,8 @@ sub parse_host_filtering { } } @down_hosts = uniq(@down_hosts); - return(\%ncores, \%ncpus, \%time_to_login, \%maxlen, \%echo, \@down_hosts); + return(\%nsockets, \%ncores, \%nthreads, \%time_to_login, + \%maxlen, \%echo, \@down_hosts); } sub parallelized_host_filtering { @@ -3701,14 +3725,16 @@ sub parallelized_host_filtering { return($job->{'wrapped'}); } - my(@cores, @cpus, @maxline, @echo); + my(@sockets, @cores, @threads, @maxline, @echo); while (my ($host, $sshlogin) = each %Global::host) { if($host eq ":") { next } # The 'true' is used to get the $host out later + push(@sockets, $host."\t"."true $host; ". + sshwrapped($sshlogin,"parallel --number-of-sockets")."\n\0"); push(@cores, $host."\t"."true $host; ". sshwrapped($sshlogin,"parallel --number-of-cores")."\n\0"); - push(@cpus, $host."\t"."true $host; ". - sshwrapped($sshlogin,"parallel --number-of-cpus")."\n\0"); + push(@threads, $host."\t"."true $host; ". + sshwrapped($sshlogin,"parallel --number-of-threads")."\n\0"); push(@maxline, $host."\t"."true $host; ". sshwrapped($sshlogin,"parallel --max-line-length-allowed")."\n\0"); # 'echo' is used to get the fastest possible ssh login time @@ -3735,7 +3761,7 @@ sub parallelized_host_filtering { if(not fork()) { # Give the commands to run to the $cmd close $host_fh; - print $in @cores, @cpus, @maxline, @echo; + print $in @sockets, @cores, @threads, @maxline, @echo; close $in; exit(); } @@ -6327,18 +6353,26 @@ sub ncpus { my $sshcmd = $self->sshcommand(); my $serverlogin = $self->serverlogin(); if($serverlogin eq ":") { - if($opt::use_cpus_instead_of_cores) { - $self->{'ncpus'} = no_of_cpus(); + if($opt::use_sockets_instead_of_threads) { + $self->{'ncpus'} = socket_core_thread()->{'sockets'}; + } elsif($opt::use_cores_instead_of_threads) { + $self->{'ncpus'} = socket_core_thread()->{'cores'}; } else { - $self->{'ncpus'} = no_of_cores(); + $self->{'ncpus'} = socket_core_thread()->{'threads'}; } } else { my $ncpu; - if($opt::use_cpus_instead_of_cores) { - $ncpu = ::qqx("echo|$sshcmd $serverlogin -- parallel --number-of-cpus"); + if($opt::use_sockets_instead_of_threads + or + $opt::use_cpus_instead_of_cores) { + $ncpu = + ::qqx("echo|$sshcmd $serverlogin -- parallel --number-of-sockets"); + } elsif($opt::use_cores_instead_of_threads) { + $ncpu = + ::qqx("echo|$sshcmd $serverlogin -- parallel --number-of-cores"); } else { - ::debug("init",qq(echo|$sshcmd $serverlogin -- parallel --number-of-cores\n)); - $ncpu = ::qqx("echo|$sshcmd $serverlogin -- parallel --number-of-cores"); + $ncpu = + ::qqx("echo|$sshcmd $serverlogin -- parallel --number-of-threads"); } chomp $ncpu; if($ncpu =~ /^\s*[0-9]+\s*$/s) { @@ -6353,472 +6387,455 @@ sub ncpus { return $self->{'ncpus'}; } -sub no_of_cpus { - # Returns: - # Number of physical CPUs - local $/ = "\n"; # If delimiter is set, then $/ will be wrong - my $no_of_cpus; - if ($^O eq 'linux') { - $no_of_cpus = no_of_cpus_gnu_linux() || no_of_cores_gnu_linux(); - } elsif ($^O eq 'freebsd') { - $no_of_cpus = no_of_cpus_freebsd(); - } elsif ($^O eq 'netbsd') { - $no_of_cpus = no_of_cpus_netbsd(); - } elsif ($^O eq 'openbsd') { - $no_of_cpus = no_of_cpus_openbsd(); - } elsif ($^O eq 'gnu') { - $no_of_cpus = no_of_cpus_hurd(); - } elsif ($^O eq 'darwin') { - $no_of_cpus = no_of_cpus_darwin(); - } elsif ($^O eq 'solaris') { - $no_of_cpus = no_of_cpus_solaris() || nproc(); - } elsif ($^O eq 'aix') { - $no_of_cpus = no_of_cpus_aix(); - } elsif ($^O eq 'hpux') { - $no_of_cpus = no_of_cpus_hpux(); - } elsif ($^O eq 'nto') { - $no_of_cpus = no_of_cpus_qnx(); - } elsif ($^O eq 'svr5') { - $no_of_cpus = no_of_cpus_openserver(); - } elsif ($^O eq 'irix') { - $no_of_cpus = no_of_cpus_irix(); - } elsif ($^O eq 'dec_osf') { - $no_of_cpus = no_of_cpus_tru64(); - } else { - $no_of_cpus = (no_of_cpus_gnu_linux() - || no_of_cpus_freebsd() - || no_of_cpus_netbsd() - || no_of_cpus_openbsd() - || no_of_cpus_hurd() - || no_of_cpus_darwin() - || no_of_cpus_solaris() - || no_of_cpus_aix() - || no_of_cpus_hpux() - || no_of_cpus_qnx() - || no_of_cpus_openserver() - || no_of_cpus_irix() - || no_of_cpus_tru64() - # Number of cores is better than no guess for #CPUs - || nproc() - ); - } - if($no_of_cpus) { - chomp $no_of_cpus; - return $no_of_cpus; - } else { - ::warning("Cannot figure out number of cpus. Using 1."); - return 1; - } -} - -sub no_of_cores { - # Returns: - # Number of CPU cores - local $/ = "\n"; # If delimiter is set, then $/ will be wrong - my $no_of_cores; - if ($^O eq 'linux') { - $no_of_cores = no_of_cores_gnu_linux(); - } elsif ($^O eq 'freebsd') { - $no_of_cores = no_of_cores_freebsd(); - } elsif ($^O eq 'netbsd') { - $no_of_cores = no_of_cores_netbsd(); - } elsif ($^O eq 'openbsd') { - $no_of_cores = no_of_cores_openbsd(); - } elsif ($^O eq 'gnu') { - $no_of_cores = no_of_cores_hurd(); - } elsif ($^O eq 'darwin') { - $no_of_cores = no_of_cores_darwin(); - } elsif ($^O eq 'solaris') { - $no_of_cores = no_of_cores_solaris() || nproc(); - } elsif ($^O eq 'aix') { - $no_of_cores = no_of_cores_aix(); - } elsif ($^O eq 'hpux') { - $no_of_cores = no_of_cores_hpux(); - } elsif ($^O eq 'nto') { - $no_of_cores = no_of_cores_qnx(); - } elsif ($^O eq 'svr5') { - $no_of_cores = no_of_cores_openserver(); - } elsif ($^O eq 'irix') { - $no_of_cores = no_of_cores_irix(); - } elsif ($^O eq 'dec_osf') { - $no_of_cores = no_of_cores_tru64(); - } else { - $no_of_cores = (no_of_cores_gnu_linux() - || no_of_cores_freebsd() - || no_of_cores_netbsd() - || no_of_cores_openbsd() - || no_of_cores_hurd() - || no_of_cores_darwin() - || no_of_cores_solaris() - || no_of_cores_aix() - || no_of_cores_hpux() - || no_of_cores_qnx() - || no_of_cores_openserver() - || no_of_cores_irix() - || no_of_cores_tru64() - || nproc() - ); - } - if($no_of_cores) { - chomp $no_of_cores; - return $no_of_cores; - } else { - ::warning("Cannot figure out number of CPU cores. Using 1."); - return 1; - } -} sub nproc { # Returns: - # Number of cores using `nproc` - my $no_of_cores = ::qqx("nproc"); - return $no_of_cores; + # Number of threads using `nproc` + my $no_of_threads = ::qqx("nproc"); + chomp $no_of_threads; + return $no_of_threads; } -sub no_of_cpus_gnu_linux { +sub no_of_sockets() { + return socket_core_thread()->{'sockets'}; +} + +sub no_of_cores() { + return socket_core_thread()->{'cores'}; +} + +sub no_of_threads() { + return socket_core_thread()->{'threads'}; +} + +sub socket_core_thread() { # Returns: - # Number of physical CPUs on GNU/Linux - # undef if not GNU/Linux - my $no_of_cpus; - my $no_of_cores; - my $no_of_active_cores; + # { + # 'sockets' => #sockets = number of socket with CPU present + # 'cores' => #cores = number of physical cores + # 'threads' => #threads = number of compute cores (hyperthreading) + # 'active' => #taskset_threads = number of taskset limited cores + # } + my $cpu; + + if ($^O eq 'linux') { + $cpu = sct_gnu_linux(); + } elsif ($^O eq 'freebsd') { + $cpu = sct_freebsd(); + } elsif ($^O eq 'netbsd') { + $cpu = sct_netbsd(); + } elsif ($^O eq 'openbsd') { + $cpu = sct_openbsd(); + } elsif ($^O eq 'gnu') { + $cpu = sct_hurd(); + } elsif ($^O eq 'darwin') { + $cpu = sct_darwin(); + } elsif ($^O eq 'solaris') { + $cpu = sct_solaris(); + } elsif ($^O eq 'aix') { + $cpu = sct_aix(); + } elsif ($^O eq 'hpux') { + $cpu = sct_hpux(); + } elsif ($^O eq 'nto') { + $cpu = sct_qnx(); + } elsif ($^O eq 'svr5') { + $cpu = sct_openserver(); + } elsif ($^O eq 'irix') { + $cpu = sct_irix(); + } elsif ($^O eq 'dec_osf') { + $cpu = sct_tru64(); + } else { + # Try all methods until you find something that works + $cpu = (sct_gnu_linux() + || sct_freebsd() + || sct_netbsd() + || sct_openbsd() + || sct_hurd() + || sct_darwin() + || sct_solaris() + || sct_aix() + || sct_hpux() + || sct_qnx() + || sct_openserver() + || sct_irix() + || sct_tru64() + ); + } + if(not $cpu) { + my $nproc = nproc(); + if($nproc) { + $cpu->{'sockets'} = + $cpu->{'cores'} = + $cpu->{'threads'} = + $cpu->{'active'} = + $nproc; + } + } + if(not $cpu) { + ::warning("Cannot figure out number of cpus. Using 1."); + $cpu->{'sockets'} = + $cpu->{'cores'} = + $cpu->{'threads'} = + $cpu->{'active'} = + 1 + } + + # Choose minimum of active and actual + my $mincpu; + $mincpu->{'sockets'} = ::min($cpu->{'sockets'},$cpu->{'active'}); + $mincpu->{'cores'} = ::min($cpu->{'cores'},$cpu->{'active'}); + $mincpu->{'threads'} = ::min($cpu->{'threads'},$cpu->{'active'}); + return $mincpu; +} + +sub sct_gnu_linux() { + # Returns: + # { 'sockets' => #sockets + # 'cores' => #cores + # 'threads' => #threads + # 'active' => #taskset_threads } + my $cpu; + local $/ = "\n"; # If delimiter is set, then $/ will be wrong if(-e "/proc/cpuinfo") { - $no_of_cpus = 0; - $no_of_cores = 0; - my %seen; - if(open(my $in_fh, "<", "/proc/cpuinfo")) { + $cpu->{'sockets'} = 0; + $cpu->{'cores'} = 0; + $cpu->{'threads'} = 0; + my %seen; + my %phy_seen; + if(open(my $in_fh, "<", "/proc/cpuinfo")) { while(<$in_fh>) { - if(/^physical id.*[:](.*)/ and not $seen{$1}++) { - $no_of_cpus++; + if(/^physical id.*[:](.*)/ and not $phy_seen{$1}++) { + $cpu->{'sockets'}++; } - /^processor.*[:]/i and $no_of_cores++; + if(/^core id.*[:](.*)/ and not $seen{$1}++) { + $cpu->{'cores'}++; + } + /^processor.*[:]/i and $cpu->{'threads'}++; } close $in_fh; } + $cpu->{'sockets'} ||= 1; + $cpu->{'cores'} ||= $cpu->{'threads'}; } if(-e "/proc/self/status") { - # if 'taskset' is used to limit number of cores - if(open(my $in_fh, "<", "/proc/self/status")) { + # if 'taskset' is used to limit number of threads + if(open(my $in_fh, "<", "/proc/self/status")) { while(<$in_fh>) { if(/^Cpus_allowed:\s*(\S+)/) { my $a = $1; $a =~ tr/,//d; - $no_of_active_cores = unpack ("%32b*", pack ("H*",$a)); + $cpu->{'active'} = unpack ("%32b*", pack ("H*",$a)); } } close $in_fh; } } - return (::min($no_of_cpus || $no_of_cores,$no_of_active_cores)); + if(grep { /\d/ } values %$cpu) { + return $cpu; + } else { + return undef; + } } -sub no_of_cores_gnu_linux { +sub sct_freebsd() { # Returns: - # Number of CPU cores on GNU/Linux - # undef if not GNU/Linux - my $no_of_cores; - my $no_of_active_cores; - if(-e "/proc/cpuinfo") { - $no_of_cores = 0; - open(my $in_fh, "<", "/proc/cpuinfo") || return undef; - while(<$in_fh>) { - /^processor.*[:]/i and $no_of_cores++; - } - close $in_fh; - } - if(-e "/proc/self/status") { - # if 'taskset' is used to limit number of cores - if(open(my $in_fh, "<", "/proc/self/status")) { - while(<$in_fh>) { - if(/^Cpus_allowed:\s*(\S+)/) { - my $a = $1; - $a =~ tr/,//d; - $no_of_active_cores = unpack ("%32b*", pack ("H*",$a)); - } - } - close $in_fh; - } - } - return (::min($no_of_cores,$no_of_active_cores)); -} - -sub no_of_cpus_freebsd { - # Returns: - # Number of physical CPUs on FreeBSD - # undef if not FreeBSD + # { 'sockets' => #sockets + # 'cores' => #cores + # 'threads' => #threads + # 'active' => #taskset_threads } local $/ = "\n"; - my $no_of_cpus = - (::qqx(qq{ sysctl -a dev.cpu | grep \%parent | awk '{ print \$2 }' | uniq | wc -l | awk '{ print \$1 }' }) + my $cpu; + $cpu->{'cores'} = (::qqx(qq{ sysctl -a dev.cpu | grep \%parent | awk '{ print \$2 }' | uniq | wc -l | awk '{ print \$1 }' }) or ::qqx(qq{ sysctl hw.ncpu | awk '{ print \$2 }' })); - chomp $no_of_cpus; - return $no_of_cpus; -} - -sub no_of_cores_freebsd { - # Returns: - # Number of CPU cores on FreeBSD - # undef if not FreeBSD - local $/ = "\n"; - my $no_of_cores = + $cpu->{'cores'} and chomp $cpu->{'cores'}; + $cpu->{'threads'} = (::qqx(qq{ sysctl hw.ncpu | awk '{ print \$2 }' }) or ::qqx(qq{ sysctl -a dev.cpu | grep \%parent | awk '{ print \$2 }' | uniq | wc -l | awk '{ print \$1 }' })); - chomp $no_of_cores; - return $no_of_cores; + $cpu->{'threads'} and chomp $cpu->{'threads'}; + $cpu->{'sockets'} ||= $cpu->{'cores'}; + + if(grep { /\d/ } values %$cpu) { + return $cpu; + } else { + return undef; + } } -sub no_of_cpus_netbsd { +sub sct_netbsd() { # Returns: - # Number of physical CPUs on NetBSD - # undef if not NetBSD + # { 'sockets' => #sockets + # 'cores' => #cores + # 'threads' => #threads + # 'active' => #taskset_threads } local $/ = "\n"; - my $no_of_cpus = ::qqx("sysctl -n hw.ncpu"); - chomp $no_of_cpus; - return $no_of_cpus; + my $cpu; + $cpu->{'cores'} = ::qqx("sysctl -n hw.ncpu"); + $cpu->{'cores'} and chomp $cpu->{'cores'}; + $cpu->{'threads'} = ::qqx("sysctl -n hw.ncpu"); + $cpu->{'threads'} and chomp $cpu->{'threads'}; + $cpu->{'sockets'} ||= $cpu->{'cores'}; + + if(grep { /\d/ } values %$cpu) { + return $cpu; + } else { + return undef; + } } -sub no_of_cores_netbsd { +sub sct_openbsd() { # Returns: - # Number of CPU cores on NetBSD - # undef if not NetBSD + # { 'sockets' => #sockets + # 'cores' => #cores + # 'threads' => #threads + # 'active' => #taskset_threads } local $/ = "\n"; - my $no_of_cores = ::qqx("sysctl -n hw.ncpu"); - chomp $no_of_cores; - return $no_of_cores; + my $cpu; + $cpu->{'cores'} = ::qqx('sysctl -n hw.ncpu'); + $cpu->{'cores'} and chomp $cpu->{'cores'}; + $cpu->{'threads'} = ::qqx('sysctl -n hw.ncpu'); + $cpu->{'threads'} and chomp $cpu->{'threads'}; + $cpu->{'sockets'} ||= $cpu->{'cores'}; + + if(grep { /\d/ } values %$cpu) { + return $cpu; + } else { + return undef; + } } -sub no_of_cpus_openbsd { +sub sct_hurd() { # Returns: - # Number of physical CPUs on OpenBSD - # undef if not OpenBSD + # { 'sockets' => #sockets + # 'cores' => #cores + # 'threads' => #threads + # 'active' => #taskset_threads } local $/ = "\n"; - my $no_of_cpus = ::qqx('sysctl -n hw.ncpu'); - chomp $no_of_cpus; - return $no_of_cpus; + my $cpu; + $cpu->{'cores'} = ::qqx("nproc"); + $cpu->{'cores'} and chomp $cpu->{'cores'}; + $cpu->{'threads'} = ::qqx("nproc"); + $cpu->{'threads'} and chomp $cpu->{'threads'}; + + if(grep { /\d/ } values %$cpu) { + return $cpu; + } else { + return undef; + } } -sub no_of_cores_openbsd { +sub sct_darwin() { # Returns: - # Number of CPU cores on OpenBSD - # undef if not OpenBSD + # { 'sockets' => #sockets + # 'cores' => #cores + # 'threads' => #threads + # 'active' => #taskset_threads } local $/ = "\n"; - my $no_of_cores = ::qqx('sysctl -n hw.ncpu'); - chomp $no_of_cores; - return $no_of_cores; -} - -sub no_of_cpus_hurd { - # Returns: - # Number of physical CPUs on HURD - # undef if not HURD - local $/ = "\n"; - my $no_of_cpus = ::qqx("nproc"); - chomp $no_of_cpus; - return $no_of_cpus; -} - -sub no_of_cores_hurd { - # Returns: - # Number of physical CPUs on HURD - # undef if not HURD - local $/ = "\n"; - my $no_of_cores = ::qqx("nproc"); - chomp $no_of_cores; - return $no_of_cores; -} - -sub no_of_cpus_darwin { - # Returns: - # Number of physical CPUs on MacOSX Darwin - # undef if not MacOSX Darwin - my $no_of_cpus = + my $cpu; + $cpu->{'cores'} = (::qqx('sysctl -n hw.physicalcpu') or ::qqx(qq{ sysctl -a hw | grep [^a-z]physicalcpu[^a-z] | awk '{ print \$2 }' })); - return $no_of_cpus; -} - -sub no_of_cores_darwin { - # Returns: - # Number of CPU cores on Mac Darwin - # undef if not Mac Darwin - my $no_of_cores = + $cpu->{'cores'} and chomp $cpu->{'cores'}; + $cpu->{'threads'} = (::qqx('sysctl -n hw.logicalcpu') or ::qqx(qq{ sysctl -a hw | grep [^a-z]logicalcpu[^a-z] | awk '{ print \$2 }' })); - return $no_of_cores; + $cpu->{'threads'} and chomp $cpu->{'threads'}; + $cpu->{'sockets'} ||= $cpu->{'cores'}; + + if(grep { /\d/ } values %$cpu) { + return $cpu; + } else { + return undef; + } } -sub no_of_cpus_solaris { +sub sct_solaris() { # Returns: - # Number of physical CPUs on Solaris - # undef if not Solaris - if(-x "/usr/sbin/psrinfo") { - my @psrinfo = ::qqx("/usr/sbin/psrinfo"); - if($#psrinfo >= 0) { - return $#psrinfo +1; - } - } - if(-x "/usr/sbin/prtconf") { - my @prtconf = ::qqx("/usr/sbin/prtconf | grep cpu..instance"); - if($#prtconf >= 0) { - return $#prtconf +1; - } - } - if(-x "/usr/sbin/prtconf") { - my @prtconf = ::qqx("/usr/sbin/prtconf | grep cpu..instance"); - if($#prtconf >= 0) { - return $#prtconf +1; - } - } - return undef; -} - -sub no_of_cores_solaris { - # Returns: - # Number of CPU cores on Solaris - # undef if not Solaris - if(-x "/usr/sbin/psrinfo") { - my @psrinfo = ::qqx("/usr/sbin/psrinfo"); - if($#psrinfo >= 0) { - return $#psrinfo +1; - } - } - if(-x "/usr/sbin/prtconf") { - my @prtconf = ::qqx("/usr/sbin/prtconf | grep cpu..instance"); - if($#prtconf >= 0) { - return $#prtconf +1; - } - } - return undef; -} - -sub no_of_cpus_aix { - # Returns: - # Number of physical CPUs on AIX - # undef if not AIX + # { 'sockets' => #sockets + # 'cores' => #cores + # 'threads' => #threads + # 'active' => #taskset_threads } local $/ = "\n"; - my $no_of_cpus = 0; + my $cpu; + if(-x "/usr/sbin/psrinfo") { + my @psrinfo = ::qqx("/usr/sbin/psrinfo"); + if($#psrinfo >= 0) { + $cpu->{'cores'} = $#psrinfo +1; + } + } + if(-x "/usr/sbin/prtconf") { + my @prtconf = ::qqx("/usr/sbin/prtconf | grep cpu..instance"); + if($#prtconf >= 0) { + $cpu->{'cores'} = $#prtconf +1; + } + } + if(-x "/usr/sbin/prtconf") { + my @prtconf = ::qqx("/usr/sbin/prtconf | grep cpu..instance"); + if($#prtconf >= 0) { + $cpu->{'cores'} = $#prtconf +1; + } + } + $cpu->{'cores'} and chomp $cpu->{'cores'}; + + if(-x "/usr/sbin/psrinfo") { + my @psrinfo = ::qqx("/usr/sbin/psrinfo"); + if($#psrinfo >= 0) { + $cpu->{'threads'} = $#psrinfo +1; + } + } + if(-x "/usr/sbin/prtconf") { + my @prtconf = ::qqx("/usr/sbin/prtconf | grep cpu..instance"); + if($#prtconf >= 0) { + $cpu->{'threads'} = $#prtconf +1; + } + } + $cpu->{'threads'} and chomp $cpu->{'threads'}; + + if(grep { /\d/ } values %$cpu) { + return $cpu; + } else { + return undef; + } +} + +sub sct_aix() { + # Returns: + # { 'sockets' => #sockets + # 'cores' => #cores + # 'threads' => #threads + # 'active' => #taskset_threads } + local $/ = "\n"; + my $cpu; if(-x "/usr/sbin/lscfg") { - open(my $in_fh, "-|", "/usr/sbin/lscfg -vs |grep proc | wc -l|tr -d ' '") - || return undef; - $no_of_cpus = <$in_fh>; - chomp ($no_of_cpus); - close $in_fh; - } - return $no_of_cpus; -} - -sub no_of_cores_aix { - # Returns: - # Number of CPU cores on AIX - # undef if not AIX - my $no_of_cores; - if(-x "/usr/bin/vmstat") { - open(my $in_fh, "-|", "/usr/bin/vmstat 1 1") || return undef; - while(<$in_fh>) { - /lcpu=([0-9]*) / and $no_of_cores = $1; + if(open(my $in_fh, "-|", "/usr/sbin/lscfg -vs |grep proc | wc -l|tr -d ' '")) { + $cpu->{'cores'} = <$in_fh>; + chomp ($cpu->{'cores'}); + close $in_fh; } - close $in_fh; } - return $no_of_cores; + if(-x "/usr/bin/vmstat") { + if(open(my $in_fh, "-|", "/usr/bin/vmstat 1 1")) { + while(<$in_fh>) { + /lcpu=([0-9]*) / and $cpu->{'threads'} = $1; + } + close $in_fh; + } + } + $cpu->{'sockets'} ||= $cpu->{'cores'}; + + if(grep { /\d/ } values %$cpu) { + return $cpu; + } else { + return undef; + } } -sub no_of_cpus_hpux { +sub sct_hpux() { # Returns: - # Number of physical CPUs on HP-UX - # undef if not HP-UX - my $no_of_cpus = + # { 'sockets' => #sockets + # 'cores' => #cores + # 'threads' => #threads + # 'active' => #taskset_threads } + local $/ = "\n"; + my $cpu; + $cpu->{'cores'} = ::qqx(qq{ /usr/bin/mpsched -s 2>&1 | grep 'Locality Domain Count' | awk '{ print \$4 }'}); - return $no_of_cpus; -} - -sub no_of_cores_hpux { - # Returns: - # Number of CPU cores on HP-UX - # undef if not HP-UX - my $no_of_cores = + $cpu->{'threads'} = ::qqx(qq{ /usr/bin/mpsched -s 2>&1 | perl -ne '/Processor Count\\D+(\\d+)/ and print "\$1\n"'}); - return $no_of_cores; + + if(grep { /\d/ } values %$cpu) { + return $cpu; + } else { + return undef; + } } -sub no_of_cpus_qnx { +sub sct_qnx() { # Returns: - # Number of physical CPUs on QNX - # undef if not QNX + # { 'sockets' => #sockets + # 'cores' => #cores + # 'threads' => #threads + # 'active' => #taskset_threads } + local $/ = "\n"; + my $cpu; # BUG: It is not known how to calculate this. - my $no_of_cpus = 0; - return $no_of_cpus; + + if(grep { /\d/ } values %$cpu) { + return $cpu; + } else { + return undef; + } } -sub no_of_cores_qnx { +sub sct_openserver() { # Returns: - # Number of CPU cores on QNX - # undef if not QNX - # BUG: It is not known how to calculate this. - my $no_of_cores = 0; - return $no_of_cores; -} - -sub no_of_cpus_openserver { - # Returns: - # Number of physical CPUs on SCO OpenServer - # undef if not SCO OpenServer - my $no_of_cpus = 0; + # { 'sockets' => #sockets + # 'cores' => #cores + # 'threads' => #threads + # 'active' => #taskset_threads } + local $/ = "\n"; + my $cpu; if(-x "/usr/sbin/psrinfo") { my @psrinfo = ::qqx("/usr/sbin/psrinfo"); if($#psrinfo >= 0) { - return $#psrinfo +1; + $cpu->{'cores'} = $#psrinfo +1; } } - return $no_of_cpus; -} - -sub no_of_cores_openserver { - # Returns: - # Number of CPU cores on SCO OpenServer - # undef if not SCO OpenServer - my $no_of_cores = 0; if(-x "/usr/sbin/psrinfo") { my @psrinfo = ::qqx("/usr/sbin/psrinfo"); if($#psrinfo >= 0) { - return $#psrinfo +1; + $cpu->{'threads'} = $#psrinfo +1; } } - return $no_of_cores; + $cpu->{'sockets'} ||= $cpu->{'cores'}; + + if(grep { /\d/ } values %$cpu) { + return $cpu; + } else { + return undef; + } } -sub no_of_cpus_irix { +sub sct_irix() { # Returns: - # Number of physical CPUs on IRIX - # undef if not IRIX - my $no_of_cpus = ::qqx(qq{ hinv | grep HZ | grep Processor | awk '{print \$1}' }); - return $no_of_cpus; + # { 'sockets' => #sockets + # 'cores' => #cores + # 'threads' => #threads + # 'active' => #taskset_threads } + local $/ = "\n"; + my $cpu; + $cpu->{'cores'} = ::qqx(qq{ hinv | grep HZ | grep Processor | awk '{print \$1}' }); + $cpu->{'cores'} and chomp $cpu->{'cores'}; + + if(grep { /\d/ } values %$cpu) { + return $cpu; + } else { + return undef; + } } -sub no_of_cores_irix { +sub sct_tru64() { # Returns: - # Number of CPU cores on IRIX - # undef if not IRIX - my $no_of_cores = ::qqx(qq{ hinv | grep HZ | grep Processor | awk '{print \$1}' }); - return $no_of_cores; -} + # { 'sockets' => #sockets + # 'cores' => #cores + # 'threads' => #threads + # 'active' => #taskset_threads } + local $/ = "\n"; + my $cpu; + $cpu->{'cores'} = ::qqx("sizer -pr"); + $cpu->{'cores'} and chomp $cpu->{'cores'}; + $cpu->{'cores'} ||= 1; + $cpu->{'sockets'} ||= $cpu->{'cores'}; + $cpu->{'threads'} ||= $cpu->{'cores'}; -sub no_of_cpus_tru64 { - # Returns: - # Number of physical CPUs on Tru64 - # undef if not Tru64 - my $no_of_cpus = ::qqx("sizer -pr"); - return $no_of_cpus; -} - -sub no_of_cores_tru64 { - # Returns: - # Number of CPU cores on Tru64 - # undef if not Tru64 - my $no_of_cores = ::qqx("sizer -pr"); - return $no_of_cores; + if(grep { /\d/ } values %$cpu) { + return $cpu; + } else { + return undef; + } } sub sshcommand { diff --git a/src/parallel.pod b/src/parallel.pod index 198e83e7..31cb3469 100644 --- a/src/parallel.pod +++ b/src/parallel.pod @@ -975,7 +975,7 @@ See also B<--resume> B<--resume-failed>. Number of jobslots on each machine. Run up to N jobs in parallel. 0 means as many as possible. Default is 100% which will run one job per -CPU core on each machine. +CPU on each machine. If B<--semaphore> is set, the default is 1 thus making a mutex. @@ -988,8 +988,9 @@ If B<--semaphore> is set, the default is 1 thus making a mutex. =item B<-P> I<+N> -Add N to the number of CPU cores. Run this many jobs in parallel. -See also B<--use-cpus-instead-of-cores>. +Add N to the number of CPUs. Run this many jobs in parallel. See +also B<--use-cores-instead-of-threads> and +B<--use-sockets-instead-of-threads>. =item B<--jobs> I<-N> @@ -1000,9 +1001,10 @@ See also B<--use-cpus-instead-of-cores>. =item B<-P> I<-N> -Subtract N from the number of CPU cores. Run this many jobs in parallel. +Subtract N from the number of CPUs. Run this many jobs in parallel. If the evaluated number is less than 1 then 1 will be used. See also -B<--use-cpus-instead-of-cores>. +B<--use-cores-instead-of-threads> and +B<--use-sockets-instead-of-threads>. =item B<--jobs> I% @@ -1013,8 +1015,9 @@ B<--use-cpus-instead-of-cores>. =item B<-P> I% -Multiply N% with the number of CPU cores. Run this many jobs in -parallel. See also B<--use-cpus-instead-of-cores>. +Multiply N% with the number of CPUs. Run this many jobs in +parallel. See also B<--use-cores-instead-of-threads> and +B<--use-sockets-instead-of-threads>. =item B<--jobs> I @@ -1392,13 +1395,13 @@ inspired by bash's parameter expansion: =item B<--progress> Show progress of computations. List the computers involved in the task -with number of CPU cores detected and the max number of jobs to -run. After that show progress for each computer: number of running -jobs, number of completed jobs, and percentage of all jobs done by -this computer. The percentage will only be available after all jobs -have been scheduled as GNU B only read the next job when -ready to schedule it - this is to avoid wasting time and memory by -reading everything at startup. +with number of CPUs detected and the max number of jobs to run. After +that show progress for each computer: number of running jobs, number +of completed jobs, and percentage of all jobs done by this +computer. The percentage will only be available after all jobs have +been scheduled as GNU B only read the next job when ready to +schedule it - this is to avoid wasting time and memory by reading +everything at startup. By sending GNU B SIGUSR2 you can toggle turning on/off B<--progress> on a running GNU B process. @@ -1450,16 +1453,29 @@ exit (used by GNU B itself to determine the line length on remote computers). -=item B<--number-of-cpus> +=item B<--number-of-cpus> (obsolete) -Print the number of physical CPUs and exit (used by GNU B -itself to determine the number of physical CPUs on remote computers). +Print the number of physical CPU cores and exit. -=item B<--number-of-cores> +=item B<--number-of-cores> (alpha testing) -Print the number of CPU cores and exit (used by GNU B itself -to determine the number of CPU cores on remote computers). +Print the number of physical CPU cores and exit (used by GNU B itself +to determine the number of physical CPU cores on remote computers). + + +=item B<--number-of-sockets> (alpha testing) + +Print the number of filled CPU sockets and exit (used by GNU +B itself to determine the number of filled CPU sockets on +remote computers). + + +=item B<--number-of-threads> (alpha testing) + +Print the number of hyperthreaded CPU cores and exit (used by GNU +B itself to determine the number of hyperthreaded CPU cores +on remote computers). =item B<--no-keep-order> @@ -2206,11 +2222,11 @@ I seconds after starting each ssh. I can be less than 1 seconds. -=item B<-S> I<[@hostgroups/][ncores/]sshlogin[,[@hostgroups/][ncores/]sshlogin[,...]]> +=item B<-S> I<[@hostgroups/][ncpus/]sshlogin[,[@hostgroups/][ncpus/]sshlogin[,...]]> =item B<-S> I<@hostgroup> -=item B<--sshlogin> I<[@hostgroups/][ncores/]sshlogin[,[@hostgroups/][ncores/]sshlogin[,...]]> +=item B<--sshlogin> I<[@hostgroups/][ncpus/]sshlogin[,[@hostgroups/][ncpus/]sshlogin[,...]]> =item B<--sshlogin> I<@hostgroup> @@ -2224,10 +2240,10 @@ will always be added to a hostgroup named the same as I. If only the I<@hostgroup> is given, only the sshlogins in that hostgroup will be used. Multiple I<@hostgroup> can be given. -GNU B will determine the number of CPU cores on the remote +GNU B will determine the number of CPUs on the remote computers and run the number of jobs as specified by B<-j>. If the -number I is given GNU B will use this number for -number of CPU cores on the host. Normally I will not be +number I is given GNU B will use this number for +number of CPUs on the host. Normally I will not be needed. An I is of the form: @@ -2268,24 +2284,24 @@ lines. Empty lines and lines starting with '#' are ignored. Example: server.example.com username@server2.example.com - 8/my-8-core-server.example.com + 8/my-8-cpu-server.example.com 2/my_other_username@my-dualcore.example.net # This server has SSH running on port 2222 ssh -p 2222 server.example.net 4/ssh -p 2222 quadserver.example.net # Use a different ssh program myssh -p 2222 -l myusername hexacpu.example.net - # Use a different ssh program with default number of cores + # Use a different ssh program with default number of CPUs //usr/local/bin/myssh -p 2222 -l myusername hexacpu - # Use a different ssh program with 6 cores + # Use a different ssh program with 6 CPUs 6//usr/local/bin/myssh -p 2222 -l myusername hexacpu - # Assume 16 cores on the local computer + # Assume 16 CPUs on the local computer 16/: # Put server1 in hostgroup1 @hostgroup1/server1 # Put myusername@server2 in hostgroup1+hostgroup2 @hostgroup1+hostgroup2/myusername@server2 - # Force 4 cores and put 'ssh -p 2222 server3' in hostgroup1 + # Force 4 CPUs and put 'ssh -p 2222 server3' in hostgroup1 @hostgroup1/4/ssh -p 2222 server3 When using a different ssh program the last argument must be the hostname. @@ -2553,16 +2569,46 @@ Use the replacement string I instead of B<{.}> for input line without extension. -=item B<--use-cpus-instead-of-cores> +=item B<--use-sockets-instead-of-threads> (alpha testing) -Count the number of physical CPUs instead of CPU cores. When computing -how many jobs to run simultaneously relative to the number of CPU cores -you can ask GNU B to instead look at the number of physical -CPUs. This will make sense for computers that have hyperthreading as -two jobs running on one CPU with hyperthreading will run slower than -two jobs running on two physical CPUs. Some multi-core CPUs can run -faster if only one thread is running per physical CPU. Most users will -not need this option. +=item B<--use-cores-instead-of-threads> (alpha testing) + +=item B<--use-cpus-instead-of-cores> (obsolete) + +Determine how GNU B counts the number of CPUs. GNU +B uses this number when the number of jobslots is computed +relative to the number of CPUs (e.g. 100% or +1). + +CPUs can be counted in three different ways: + +=over 8 + +=item sockets + +The number of filled CPU sockets (i.e. the number of physical chips). + +=item cores + +The number of physical cores (i.e. the number of physical compute +cores). + +=item threads + +The number of hyperthreaded cores (i.e. the number of virtual +cores - with some of them possibly being hyperthreaded) + +=back + +Normally the number of CPUs is computed as the number of CPU +threads. With B<--use-sockets-instead-of-threads> or +B<--use-cores-instead-of-threads> you can force it to be computed as +the number of filled sockets or number of cores instead. + +Most users will not need these options. + +B<--use-cpus-instead-of-cores> is a (misleading) alias for +B<--use-sockets-instead-of-threads> and is kept for backwards +compatibility. =item B<-v> @@ -2669,8 +2715,7 @@ using B run: parallel gzip --best ::: *.html -To convert *.wav to *.mp3 using LAME running one process per CPU core -run: +To convert *.wav to *.mp3 using LAME running one process per CPU run: parallel lame {} -o {.}.mp3 ::: *.wav @@ -2725,8 +2770,8 @@ file: convert -geometry 120 foo.jpg thumb_foo.jpg -This will run with number-of-cpu-cores jobs in parallel for all jpg -files in a directory: +This will run with number-of-cpus jobs in parallel for all jpg files +in a directory: ls *.jpg | parallel convert -geometry 120 {} thumb_{} @@ -2879,7 +2924,7 @@ Create a directory for each zip-file and unzip it in that dir: parallel 'mkdir {.}; cd {.}; unzip ../{}' ::: *.zip Recompress all .gz files in current directory using B running 1 -job per CPU core in parallel: +job per CPU in parallel: parallel "zcat {} | bzip2 >{.}.bz2 && rm {}" ::: *.gz @@ -3430,7 +3475,7 @@ GNU B can often speed this up. find . -type f | parallel -k -j150% -n 1000 -m grep -H -n STRING {} -This will run 1.5 job per core, and give 1000 arguments to B. +This will run 1.5 job per CPU, and give 1000 arguments to B. =head1 EXAMPLE: Grepping n lines for m regular expressions. @@ -3491,13 +3536,13 @@ If it still does not fit in memory you can do this: parallel --pipepart -a regexps.txt --block 1M grep -Ff - -n bigfile | sort -un | perl -pe 's/^\d+://' -The 1M should be your free memory divided by the number of cores and +The 1M should be your free memory divided by the number of CPU threads and divided by 200 for B and by 1000 for normal B. On GNU/Linux you can do: free=$(awk '/^((Swap)?Cached|MemFree|Buffers):/ { sum += $2 } END { print sum }' /proc/meminfo) - percpu=$((free / 200 / $(parallel --number-of-cores)))k + percpu=$((free / 200 / $(parallel --number-of-threads)))k parallel --pipepart -a regexps.txt --block $percpu --compress \ grep -F -f - -n bigfile | @@ -3607,13 +3652,13 @@ To include the local computer add the special sshlogin ':' to the list: server3.example.com : -GNU B will try to determine the number of CPU cores on each -of the remote computers, and run one job per CPU core - even if the -remote computers do not have the same number of CPU cores. +GNU B will try to determine the number of CPUs on each of +the remote computers, and run one job per CPU - even if the remote +computers do not have the same number of CPUs. -If the number of CPU cores on the remote computers is not identified -correctly the number of CPU cores can be added in front. Here the -computer has 8 CPU cores. +If the number of CPUs on the remote computers is not identified +correctly the number of CPUs can be added in front. Here the computer +has 8 CPUs. seq 10 | parallel --sshlogin 8/server.example.com echo @@ -3691,7 +3736,8 @@ the special short hand I<-S ..> can be used: =head1 EXAMPLE: Distributing work to local and remote computers -Convert *.mp3 to *.ogg running one process per CPU core on local computer and server2: +Convert *.mp3 to *.ogg running one process per CPU on local computer +and server2: parallel --trc {.}.ogg -S server2,: \ 'mpg321 -w - {} | oggenc -q0 - -o {.}.ogg' ::: *.mp3 @@ -3956,7 +4002,7 @@ To run 100 processes simultaneously do: As there is not a I the jobs will be evaluated by the shell. -=head1 EXAMPLE: Processing a big file using more cores +=head1 EXAMPLE: Processing a big file using more CPUs To process a big file or some output you can use B<--pipe> to split up the data into blocks and pipe the blocks into the processing program. @@ -3966,8 +4012,8 @@ If the program is B you can do: cat bigfile | parallel --pipe --recend '' -k gzip -9 > bigfile.gz This will split B into blocks of 1 MB and pass that to B in parallel. One B will be run per CPU core. The output of -B will be kept in order and saved to B +-9> in parallel. One B will be run per CPU. The output of B will be kept in order and saved to B B works fine if the output is appended, but some processing does not work like that - for example sorting. For this GNU B can diff --git a/src/parallel_design.pod b/src/parallel_design.pod index 3708ccca..3c5fd7f8 100644 --- a/src/parallel_design.pod +++ b/src/parallel_design.pod @@ -94,9 +94,11 @@ user having to know the location. So if the user's path includes dir that makes most sense for the sysadmin. -=head3 env_parallel.bash / env_parallel.zsh / env_parallel.ksh / env_parallel.pdksh +=head3 env_parallel.bash / env_parallel.sh / env_parallel.ash / +env_parallel.dash / env_parallel.zsh / env_parallel.ksh / +env_parallel.mksh -B defines the function +B defines the function B. It uses B and B to dump the configuration (with a few exceptions) into B<$PARALLEL_ENV> before running GNU B. @@ -145,7 +147,7 @@ This is then all saved in B<$PARALLEL_ENV>. GNU B is called, and B<$PARALLEL_ENV> is deleted. -=head2 parset +=head2 parset (supported in sh, ash, dash, bash, zsh, ksh, mksh) B is a shell function. This is the reason why B can set variables: It runs in the shell which is calling it. @@ -327,7 +329,9 @@ It is made this way to be compatible with B<*csh>/B. < $FILE perl -e 'while(@ARGV) { sysseek(STDIN,shift,0) || die; $left = shift; - while($read = sysread(STDIN,$buf, ($left > 131072 ? 131072 : $left))){ + while($read = + sysread(STDIN,$buf, + ($left > 131072 ? 131072 : $left))){ $left -= $read; syswrite(STDOUT,$buf); } @@ -343,7 +347,8 @@ and send it to STDOUT. =item --transfer ssh $SSHLOGIN mkdir -p ./$WORKDIR; - rsync --protocol 30 -rlDzR -essh ./{} $SSHLOGIN:./$WORKDIR; + rsync --protocol 30 -rlDzR \ + -essh ./{} $SSHLOGIN:./$WORKDIR; ssh $SSHLOGIN "$COMMAND" Read about B<--protocol 30> in the section B. @@ -359,8 +364,10 @@ Read about B<--protocol 30> in the section B. =item --return I $COMMAND; _EXIT_status=$?; mkdir -p $WORKDIR; - rsync --protocol 30 --rsync-path=cd\ ./$WORKDIR\;\ rsync \ - -rlDzR -essh $SSHLOGIN:./$FILE ./$WORKDIR; exit $_EXIT_status; + rsync --protocol 30 \ + --rsync-path=cd\ ./$WORKDIR\;\ rsync \ + -rlDzR -essh $SSHLOGIN:./$FILE ./$WORKDIR; + exit $_EXIT_status; The B<--rsync-path=cd ...> is needed because old versions of B do not support B<--no-implied-dirs>. @@ -374,7 +381,8 @@ wrapping 'sh -c' is enough? $RETURN is the wrapper from B<--return> $COMMAND; _EXIT_status=$?; $RETURN; - ssh $SSHLOGIN \(rm\ -f\ ./$WORKDIR/{}\;\ rmdir\ ./$WORKDIR\ \>\&/dev/null\;\); + ssh $SSHLOGIN \(rm\ -f\ ./$WORKDIR/{}\;\ + rmdir\ ./$WORKDIR\ \>\&/dev/null\;\); exit $_EXIT_status; B<$_EXIT_status>: see B<--return> above. @@ -496,7 +504,7 @@ And this will again work just fine, as long as you are running a single command. When you are running a composed command you need nice to apply to the whole command, and it gets harder still: - parallel -S server -q nice bash -c 'command1 ...; command2 | command3' + parallel -S server -q nice bash -c 'command1 ...; cmd2 | cmd3' It is not impossible, but by using B<--nice> GNU B will do the right thing for you. Similarly when transferring files: It starts @@ -824,7 +832,8 @@ B had been in its normal mode. The script looks like this: < file perl -e 'while(@ARGV) { sysseek(STDIN,shift,0) || die; $left = shift; - while($read = sysread(STDIN,$buf, ($left > 32768 ? 32768 : $left))){ + while($read = sysread(STDIN,$buf, + ($left > 131072 ? 131072 : $left))){ $left -= $read; syswrite(STDOUT,$buf); } }' startbyte length_in_bytes @@ -1135,6 +1144,23 @@ Unfortunately it is not always possible to predict the root cause of the error. +=head2 Determine number of CPUs + +CPUs is an ambiguous term. It can mean the number of socket filled +(i.e. the number of physical chips). It can mean the number of cores +(i.e. the number of physical compute cores). It can mean the number of +hyperthreaded cores (i.e. the number of virtual cores - with some of +them possibly being hyperthreaded). + +On ark.intel.com Intel uses the terms I and I for +number of physical cores and the number of hyperthreaded cores +respectively. + +GNU B uses uses I as the number of compute units and +the terms I, I, and I to specify how the +number of compute units is calculated. + + =head2 Computation of load Contrary to the obvious B<--load> does not use load average. This is @@ -1175,6 +1201,7 @@ respectively. The Signal column has been renamed to _Signal due to Signal being a reserved word in MySQL. + =head2 Logo The logo is inspired by the Cafe Wall illusion. The font is DejaVu @@ -1237,6 +1264,7 @@ Will that require 2x block size memory? These decisions were relevant for earlier versions of GNU B, but not the current version. They are kept here as historical record. + =head2 --tollef You can read about the history of GNU B on diff --git a/testsuite/tests-to-run/parallel-polarhome.sh b/testsuite/tests-to-run/parallel-polarhome.sh index 933c6f11..4fd30f8b 100644 --- a/testsuite/tests-to-run/parallel-polarhome.sh +++ b/testsuite/tests-to-run/parallel-polarhome.sh @@ -18,8 +18,8 @@ P="$P_WORKING" POLAR=`parallel -k echo {}.polarhome.com ::: $P` S_POLAR=`parallel -k echo -S 1/{}.polarhome.com ::: $P` -# 2018-04-22 TIMEOUT=20 -TIMEOUT=25 +# 2018-04-22 MAXTIME=20 +MAXTIME=25 RETRIES=4 parallel --retries $RETRIES rsync -a /usr/local/bin/{parallel,env_parallel,env_parallel.*,parcat} ::: redhat.polarhome.com:bin/ @@ -28,9 +28,9 @@ doit() { # Avoid the stupid /etc/issue.net banner at Polarhome: -oLogLevel=quiet PARALLEL_SSH="ssh -oLogLevel=quiet" export PARALLEL_SSH - export TIMEOUT + export MAXTIME export RETRIES - echo TIMEOUT=$TIMEOUT RETRIES=$RETRIES + echo MAXTIME=$MAXTIME RETRIES=$RETRIES copy() { # scp, but atomic (avoid half files if disconnected) @@ -43,19 +43,19 @@ doit() { export -f copy par_nonall() { - parallel -j15 -k --retries $RETRIES --timeout $TIMEOUT --delay 0.1 --tag \ + parallel -j15 -k --retries $RETRIES --timeout $MAXTIME --delay 0.1 --tag \ --nonall $S_POLAR --argsep ,:- \ 'source setupenv >&/dev/null || . `pwd`/setupenv;' "$@" } export -f par_nonall echo '### Copy commands to servers' - parallel -vkj15 --retries $RETRIES --timeout $TIMEOUT --delay 0.03 --tag \ + parallel -vkj15 --retries $RETRIES --timeout $MAXTIME --delay 0.03 --tag \ copy {2} {1} {1/} \ ::: bin/{parallel,env_parallel,env_parallel.*,parcat,stdout} \ ::: $POLAR echo Done copying - + # Test empty command test_empty_cmd() { echo '### Test if empty command in process list causes problems' @@ -65,11 +65,19 @@ doit() { export -f test_empty_cmd PARALLEL='--env test_empty_cmd' par_nonall test_empty_cmd 2>&1 - par_nonall parallel echo Works on {} ::: '`hostname`' 2>&1 par_nonall "stdout parallel --tmpdir / echo ::: test read-only tmp |" \ "perl -pe '\$exit += s:/[a-z0-9_]+.arg:/XXXXXXXX.arg:gi; \$exit += s/[0-9][0-9][0-9][0-9]/0000/gi; END { exit not \$exit }' &&" \ "echo OK readonly tmp" 2>&1 + + echo + echo '### --number-of-cores/--number-of-cpus should work with no error' + echo + par_nonall parallel --number-of-sockets 2>&1 + par_nonall parallel --number-of-cores 2>&1 + par_nonall parallel --number-of-threads 2>&1 + par_nonall parallel --number-of-cpus 2>&1 + echo echo '### Does exporting a bash function kill parallel' echo diff --git a/testsuite/wanted-results/parallel-polarhome b/testsuite/wanted-results/parallel-polarhome index 82884b74..ce31257a 100644 --- a/testsuite/wanted-results/parallel-polarhome +++ b/testsuite/wanted-results/parallel-polarhome @@ -1,4 +1,4 @@ -TIMEOUT=25 RETRIES=4 +MAXTIME=25 RETRIES=4 ### Copy commands to servers bin/parallel openbsd.polarhome.com copy openbsd.polarhome.com bin/parallel parallel bin/parallel tru64.polarhome.com copy tru64.polarhome.com bin/parallel parallel @@ -184,6 +184,29 @@ bin/env_parallel.ksh hurd.polarhome.com copy hurd.polarhome.com bin/env_parallel bin/env_parallel.ksh freebsd.polarhome.com copy freebsd.polarhome.com bin/env_parallel.ksh env_parallel.ksh bin/env_parallel.ksh ubuntu.polarhome.com copy ubuntu.polarhome.com bin/env_parallel.ksh env_parallel.ksh bin/env_parallel.ksh openindiana.polarhome.com copy openindiana.polarhome.com bin/env_parallel.ksh env_parallel.ksh +bin/env_parallel.mksh openbsd.polarhome.com copy openbsd.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh tru64.polarhome.com copy tru64.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh debian.polarhome.com copy debian.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh redhat.polarhome.com copy redhat.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh netbsd.polarhome.com copy netbsd.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh macosx.polarhome.com copy macosx.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh miros.polarhome.com copy miros.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh centos.polarhome.com copy centos.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh unixware.polarhome.com copy unixware.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh pidora.polarhome.com copy pidora.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh scosysv.polarhome.com copy scosysv.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh raspbian.polarhome.com copy raspbian.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh solaris-x86.polarhome.com copy solaris-x86.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh aix.polarhome.com copy aix.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh mandriva.polarhome.com copy mandriva.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh debian-ppc.polarhome.com copy debian-ppc.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh suse.polarhome.com copy suse.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh solaris.polarhome.com copy solaris.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh hpux.polarhome.com copy hpux.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh hurd.polarhome.com copy hurd.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh freebsd.polarhome.com copy freebsd.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh ubuntu.polarhome.com copy ubuntu.polarhome.com bin/env_parallel.mksh env_parallel.mksh +bin/env_parallel.mksh openindiana.polarhome.com copy openindiana.polarhome.com bin/env_parallel.mksh env_parallel.mksh bin/env_parallel.pdksh openbsd.polarhome.com copy openbsd.polarhome.com bin/env_parallel.pdksh env_parallel.pdksh bin/env_parallel.pdksh tru64.polarhome.com copy tru64.polarhome.com bin/env_parallel.pdksh env_parallel.pdksh bin/env_parallel.pdksh debian.polarhome.com copy debian.polarhome.com bin/env_parallel.pdksh env_parallel.pdksh @@ -388,52 +411,143 @@ ubuntu.polarhome.com Works on ubuntu unixware.polarhome.com Works on unixware.polarhome.com unixware.polarhome.com UX:sh (/bin/sh): ERROR: source: Not found aix.polarhome.com Error in tempfile() using /XXXXXXXX.arg: Could not create temp file /XXXXXXXX.arg: The file access permissions do not allow the specified action. at /home/t/tange/bin/parallel line 0000 -aix.polarhome.com OK +aix.polarhome.com OK readonly tmp centos.polarhome.com Error in tempfile() using /XXXXXXXX.arg: Parent directory (/) is not writable centos.polarhome.com at /home/t/tange/bin/parallel line 0000 -centos.polarhome.com OK +centos.polarhome.com OK readonly tmp debian-ppc.polarhome.com Error in tempfile() using template /XXXXXXXX.arg: Could not create temp file /XXXXXXXX.arg: Permission denied at /home/t/tange/bin/parallel line 0000. -debian-ppc.polarhome.com OK +debian-ppc.polarhome.com OK readonly tmp debian.polarhome.com Error in tempfile() using template /XXXXXXXX.arg: Could not create temp file /XXXXXXXX.arg: Permission denied at /home/t/tange/bin/parallel line 0000. -debian.polarhome.com OK +debian.polarhome.com OK readonly tmp freebsd.polarhome.com Syntax error: Bad fd number hpux.polarhome.com No such file or directory: bash macosx.polarhome.com Error in tempfile() using /XXXXXXXX.arg: Could not create temp file /XXXXXXXX.arg: Permission denied at /Users/tange/bin/parallel line 0000 -macosx.polarhome.com OK +macosx.polarhome.com OK readonly tmp mandriva.polarhome.com Error in tempfile() using /XXXXXXXX.arg: Could not create temp file /XXXXXXXX.arg: Permission denied at /home/t/tange/bin/parallel line 0000 -mandriva.polarhome.com OK +mandriva.polarhome.com OK readonly tmp miros.polarhome.com Error in tempfile() using /XXXXXXXX.arg: Parent directory (/) is not writable miros.polarhome.com at /home/t/tange/bin/parallel line 0000 -miros.polarhome.com OK +miros.polarhome.com OK readonly tmp netbsd.polarhome.com Error in tempfile() using template /XXXXXXXX.arg: Could not create temp file /XXXXXXXX.arg: Permission denied at /home/t/tange/bin/parallel line 0000. openbsd.polarhome.com Error in tempfile() using /XXXXXXXX.arg: Could not create temp file /XXXXXXXX.arg: Permission denied at /home/t/tange/bin/parallel line 0000 -openbsd.polarhome.com OK +openbsd.polarhome.com OK readonly tmp openindiana.polarhome.com Error in tempfile() using /XXXXXXXX.arg: Could not create temp file /XXXXXXXX.arg: Permission denied at /u/t/tange/bin/parallel line 0000 -openindiana.polarhome.com OK +openindiana.polarhome.com OK readonly tmp pidora.polarhome.com Error in tempfile() using template /XXXXXXXX.arg: Could not create temp file /XXXXXXXX.arg: Permission denied at /home/t/tange/bin/parallel line 0000. -pidora.polarhome.com OK +pidora.polarhome.com OK readonly tmp raspbian.polarhome.com Error in tempfile() using /XXXXXXXX.arg: Could not create temp file /XXXXXXXX.arg: Permission denied at /home/t/tange/bin/parallel line 0000 -raspbian.polarhome.com OK +raspbian.polarhome.com OK readonly tmp redhat.polarhome.com Error in tempfile() using /XXXXXXXX.arg: Could not create temp file /XXXXXXXX.arg: Permission denied at /home/t/tange/bin/parallel line 0000 -redhat.polarhome.com OK +redhat.polarhome.com OK readonly tmp scosysv.polarhome.com Error in tempfile() using /XXXXXXXX.arg: Parent directory (/) is not writable scosysv.polarhome.com at /home/t/tange/bin/parallel line 0000 -scosysv.polarhome.com OK +scosysv.polarhome.com OK readonly tmp solaris-x86.polarhome.com Error in tempfile() using /XXXXXXXX.arg: Could not create temp file /XXXXXXXX.arg: Permission denied at ~/bin/parallel line 0000 -solaris-x86.polarhome.com OK +solaris-x86.polarhome.com OK readonly tmp solaris.polarhome.com Error in tempfile() using /XXXXXXXX.arg: Parent directory (/) is not writable solaris.polarhome.com at /home/t/tange/bin/parallel line 0000 -solaris.polarhome.com OK +solaris.polarhome.com OK readonly tmp suse.polarhome.com Error in tempfile() using /XXXXXXXX.arg: Could not create temp file /XXXXXXXX.arg: Permission denied at /home/t/tange/bin/parallel line 0000. -suse.polarhome.com OK +suse.polarhome.com OK readonly tmp tru64.polarhome.com Error in tempfile() using /XXXXXXXX.arg: Parent directory (/) is not writable tru64.polarhome.com at /home/t/tange/bin/parallel line 0000 -tru64.polarhome.com OK +tru64.polarhome.com OK readonly tmp ubuntu.polarhome.com Error in tempfile() using template /XXXXXXXX.arg: Could not create temp file /XXXXXXXX.arg: Permission denied at /home/t/tange/bin/parallel line 0000. -ubuntu.polarhome.com OK +ubuntu.polarhome.com OK readonly tmp unixware.polarhome.com UX:sh (/bin/sh): ERROR: source: Not found unixware.polarhome.com UX:env: ERROR: No such file or directory: bash +### --number-of-cores/--number-of-cpus should work with no error + +aix.polarhome.com 1 +centos.polarhome.com 1 +debian-ppc.polarhome.com 1 +debian.polarhome.com 1 +freebsd.polarhome.com Syntax error: Bad fd number +macosx.polarhome.com 2 +mandriva.polarhome.com 1 +miros.polarhome.com 1 +netbsd.polarhome.com 1 +openbsd.polarhome.com 1 +openindiana.polarhome.com 1 +pidora.polarhome.com 1 +raspbian.polarhome.com 1 +redhat.polarhome.com 1 +scosysv.polarhome.com 1 +solaris-x86.polarhome.com +solaris.polarhome.com +suse.polarhome.com 1 +tru64.polarhome.com 1 +ubuntu.polarhome.com 1 +unixware.polarhome.com 1 +unixware.polarhome.com UX:sh (/bin/sh): ERROR: source: Not found +aix.polarhome.com 1 +centos.polarhome.com 1 +debian-ppc.polarhome.com 1 +debian.polarhome.com 2 +freebsd.polarhome.com Syntax error: Bad fd number +macosx.polarhome.com 2 +mandriva.polarhome.com 1 +miros.polarhome.com 1 +netbsd.polarhome.com 1 +openbsd.polarhome.com 1 +openindiana.polarhome.com 1 +pidora.polarhome.com 1 +raspbian.polarhome.com 1 +redhat.polarhome.com 2 +scosysv.polarhome.com 1 +solaris-x86.polarhome.com 1 +solaris.polarhome.com 2 +suse.polarhome.com 1 +tru64.polarhome.com 1 +ubuntu.polarhome.com 2 +unixware.polarhome.com 1 +unixware.polarhome.com UX:sh (/bin/sh): ERROR: source: Not found +aix.polarhome.com 1 +centos.polarhome.com 1 +debian-ppc.polarhome.com 1 +debian.polarhome.com 2 +freebsd.polarhome.com Syntax error: Bad fd number +macosx.polarhome.com 2 +mandriva.polarhome.com 1 +miros.polarhome.com 1 +netbsd.polarhome.com 1 +openbsd.polarhome.com 1 +openindiana.polarhome.com 1 +pidora.polarhome.com 1 +raspbian.polarhome.com 1 +redhat.polarhome.com 2 +scosysv.polarhome.com 1 +solaris-x86.polarhome.com 1 +solaris.polarhome.com 2 +suse.polarhome.com 1 +tru64.polarhome.com 1 +ubuntu.polarhome.com 2 +unixware.polarhome.com 1 +unixware.polarhome.com UX:sh (/bin/sh): ERROR: source: Not found +aix.polarhome.com 1 +centos.polarhome.com 1 +debian-ppc.polarhome.com 1 +debian.polarhome.com 2 +freebsd.polarhome.com Syntax error: Bad fd number +macosx.polarhome.com 2 +mandriva.polarhome.com 1 +miros.polarhome.com 1 +netbsd.polarhome.com 1 +openbsd.polarhome.com 1 +openindiana.polarhome.com 1 +pidora.polarhome.com 1 +raspbian.polarhome.com 1 +redhat.polarhome.com 2 +scosysv.polarhome.com 1 +solaris-x86.polarhome.com 1 +solaris.polarhome.com 2 +suse.polarhome.com 1 +tru64.polarhome.com 1 +ubuntu.polarhome.com 2 +unixware.polarhome.com 1 +unixware.polarhome.com UX:sh (/bin/sh): ERROR: source: Not found + ### Does exporting a bash function kill parallel aix.polarhome.com bash only A @@ -491,6 +605,7 @@ aix.polarhome.com /home/t/tange/.shrc aix.polarhome.com /home/t/tange/.zshenv aix.polarhome.com /home/t/tange/.config/fish/config.fish aix.polarhome.com /home/t/tange/.kshrc +aix.polarhome.com /home/t/tange/.mkshrc aix.polarhome.com /home/t/tange/.profile aix.polarhome.com /home/t/tange/.cshrc aix.polarhome.com /home/t/tange/.tcshrc @@ -501,6 +616,7 @@ centos.polarhome.com /home/t/tange/.shrc centos.polarhome.com /home/t/tange/.zshenv centos.polarhome.com /home/t/tange/.config/fish/config.fish centos.polarhome.com /home/t/tange/.kshrc +centos.polarhome.com /home/t/tange/.mkshrc centos.polarhome.com /home/t/tange/.profile centos.polarhome.com /home/t/tange/.cshrc centos.polarhome.com /home/t/tange/.tcshrc @@ -511,6 +627,7 @@ debian-ppc.polarhome.com /home/t/tange/.shrc debian-ppc.polarhome.com /home/t/tange/.zshenv debian-ppc.polarhome.com /home/t/tange/.config/fish/config.fish debian-ppc.polarhome.com /home/t/tange/.kshrc +debian-ppc.polarhome.com /home/t/tange/.mkshrc debian-ppc.polarhome.com /home/t/tange/.profile debian-ppc.polarhome.com /home/t/tange/.cshrc debian-ppc.polarhome.com /home/t/tange/.tcshrc @@ -521,6 +638,7 @@ debian.polarhome.com /home/t/tange/.shrc debian.polarhome.com /home/t/tange/.zshenv debian.polarhome.com /home/t/tange/.config/fish/config.fish debian.polarhome.com /home/t/tange/.kshrc +debian.polarhome.com /home/t/tange/.mkshrc debian.polarhome.com /home/t/tange/.profile debian.polarhome.com /home/t/tange/.cshrc debian.polarhome.com /home/t/tange/.tcshrc @@ -532,6 +650,7 @@ macosx.polarhome.com /Users/tange/.shrc macosx.polarhome.com /Users/tange/.zshenv macosx.polarhome.com /Users/tange/.config/fish/config.fish macosx.polarhome.com /Users/tange/.kshrc +macosx.polarhome.com /Users/tange/.mkshrc macosx.polarhome.com /Users/tange/.profile macosx.polarhome.com /Users/tange/.cshrc macosx.polarhome.com /Users/tange/.tcshrc @@ -542,6 +661,7 @@ mandriva.polarhome.com /home/t/tange/.shrc mandriva.polarhome.com /home/t/tange/.zshenv mandriva.polarhome.com /home/t/tange/.config/fish/config.fish mandriva.polarhome.com /home/t/tange/.kshrc +mandriva.polarhome.com /home/t/tange/.mkshrc mandriva.polarhome.com /home/t/tange/.profile mandriva.polarhome.com /home/t/tange/.cshrc mandriva.polarhome.com /home/t/tange/.tcshrc @@ -552,6 +672,7 @@ miros.polarhome.com /home/t/tange/.shrc miros.polarhome.com /home/t/tange/.zshenv miros.polarhome.com /home/t/tange/.config/fish/config.fish miros.polarhome.com /home/t/tange/.kshrc +miros.polarhome.com /home/t/tange/.mkshrc miros.polarhome.com /home/t/tange/.profile miros.polarhome.com /home/t/tange/.cshrc miros.polarhome.com /home/t/tange/.tcshrc @@ -562,6 +683,7 @@ netbsd.polarhome.com /home/t/tange/.shrc netbsd.polarhome.com /home/t/tange/.zshenv netbsd.polarhome.com /home/t/tange/.config/fish/config.fish netbsd.polarhome.com /home/t/tange/.kshrc +netbsd.polarhome.com /home/t/tange/.mkshrc netbsd.polarhome.com /home/t/tange/.profile netbsd.polarhome.com /home/t/tange/.cshrc netbsd.polarhome.com /home/t/tange/.tcshrc @@ -572,6 +694,7 @@ openbsd.polarhome.com /home/t/tange/.shrc openbsd.polarhome.com /home/t/tange/.zshenv openbsd.polarhome.com /home/t/tange/.config/fish/config.fish openbsd.polarhome.com /home/t/tange/.kshrc +openbsd.polarhome.com /home/t/tange/.mkshrc openbsd.polarhome.com /home/t/tange/.profile openbsd.polarhome.com /home/t/tange/.cshrc openbsd.polarhome.com /home/t/tange/.tcshrc @@ -582,6 +705,7 @@ openindiana.polarhome.com /u/t/tange/.shrc openindiana.polarhome.com /u/t/tange/.zshenv openindiana.polarhome.com /u/t/tange/.config/fish/config.fish openindiana.polarhome.com /u/t/tange/.kshrc +openindiana.polarhome.com /u/t/tange/.mkshrc openindiana.polarhome.com /u/t/tange/.profile openindiana.polarhome.com /u/t/tange/.cshrc openindiana.polarhome.com /u/t/tange/.tcshrc @@ -592,6 +716,7 @@ pidora.polarhome.com /home/t/tange/.shrc pidora.polarhome.com /home/t/tange/.zshenv pidora.polarhome.com /home/t/tange/.config/fish/config.fish pidora.polarhome.com /home/t/tange/.kshrc +pidora.polarhome.com /home/t/tange/.mkshrc pidora.polarhome.com /home/t/tange/.profile pidora.polarhome.com /home/t/tange/.cshrc pidora.polarhome.com /home/t/tange/.tcshrc @@ -602,6 +727,7 @@ raspbian.polarhome.com /home/t/tange/.shrc raspbian.polarhome.com /home/t/tange/.zshenv raspbian.polarhome.com /home/t/tange/.config/fish/config.fish raspbian.polarhome.com /home/t/tange/.kshrc +raspbian.polarhome.com /home/t/tange/.mkshrc raspbian.polarhome.com /home/t/tange/.profile raspbian.polarhome.com /home/t/tange/.cshrc raspbian.polarhome.com /home/t/tange/.tcshrc @@ -612,6 +738,7 @@ redhat.polarhome.com /home/t/tange/.shrc redhat.polarhome.com /home/t/tange/.zshenv redhat.polarhome.com /home/t/tange/.config/fish/config.fish redhat.polarhome.com /home/t/tange/.kshrc +redhat.polarhome.com /home/t/tange/.mkshrc redhat.polarhome.com /home/t/tange/.profile redhat.polarhome.com /home/t/tange/.cshrc redhat.polarhome.com /home/t/tange/.tcshrc @@ -622,6 +749,7 @@ scosysv.polarhome.com /home/t/tange/.shrc scosysv.polarhome.com /home/t/tange/.zshenv scosysv.polarhome.com /home/t/tange/.config/fish/config.fish scosysv.polarhome.com /home/t/tange/.kshrc +scosysv.polarhome.com /home/t/tange/.mkshrc scosysv.polarhome.com /home/t/tange/.profile scosysv.polarhome.com /home/t/tange/.cshrc scosysv.polarhome.com /home/t/tange/.tcshrc @@ -632,6 +760,7 @@ solaris-x86.polarhome.com ~/.shrc solaris-x86.polarhome.com ~/.zshenv solaris-x86.polarhome.com ~/.config/fish/config.fish solaris-x86.polarhome.com ~/.kshrc +solaris-x86.polarhome.com ~/.mkshrc solaris-x86.polarhome.com ~/.profile solaris-x86.polarhome.com ~/.cshrc solaris-x86.polarhome.com ~/.tcshrc @@ -642,6 +771,7 @@ solaris.polarhome.com /home/t/tange/.shrc solaris.polarhome.com /home/t/tange/.zshenv solaris.polarhome.com /home/t/tange/.config/fish/config.fish solaris.polarhome.com /home/t/tange/.kshrc +solaris.polarhome.com /home/t/tange/.mkshrc solaris.polarhome.com /home/t/tange/.profile solaris.polarhome.com /home/t/tange/.cshrc solaris.polarhome.com /home/t/tange/.tcshrc @@ -652,6 +782,7 @@ suse.polarhome.com /home/t/tange/.shrc suse.polarhome.com /home/t/tange/.zshenv suse.polarhome.com /home/t/tange/.config/fish/config.fish suse.polarhome.com /home/t/tange/.kshrc +suse.polarhome.com /home/t/tange/.mkshrc suse.polarhome.com /home/t/tange/.profile suse.polarhome.com /home/t/tange/.cshrc suse.polarhome.com /home/t/tange/.tcshrc @@ -662,6 +793,7 @@ tru64.polarhome.com /home/t/tange/.shrc tru64.polarhome.com /home/t/tange/.zshenv tru64.polarhome.com /home/t/tange/.config/fish/config.fish tru64.polarhome.com /home/t/tange/.kshrc +tru64.polarhome.com /home/t/tange/.mkshrc tru64.polarhome.com /home/t/tange/.profile tru64.polarhome.com /home/t/tange/.cshrc tru64.polarhome.com /home/t/tange/.tcshrc @@ -672,6 +804,7 @@ ubuntu.polarhome.com /home/t/tange/.shrc ubuntu.polarhome.com /home/t/tange/.zshenv ubuntu.polarhome.com /home/t/tange/.config/fish/config.fish ubuntu.polarhome.com /home/t/tange/.kshrc +ubuntu.polarhome.com /home/t/tange/.mkshrc ubuntu.polarhome.com /home/t/tange/.profile ubuntu.polarhome.com /home/t/tange/.cshrc ubuntu.polarhome.com /home/t/tange/.tcshrc