output";
if ($GLOBALS["debug"]) echo $cmd."
";
system("unzip pot_files >/dev/null");
$stime = time();
$p = proc_open("$cmd", $descs, $pipes);
while (1) {
$ctime=time();
if($ctime-$stime >=2 and ! file_exists("log.1")){
if($GLOBALS["debug"]) echo "time out "."
";
terminate_job($p);
break;
}
if (file_exists("log.1")) {
list($avg_cpu, $test_steps) = calc_step_cpu("log.1");
if ($avg_cpu != 0) {
if($GLOBALS["debug"])echo "avg_cpu is ".$avg_cpu."
";
terminate_job($p);
$test_result = 1;
break;
}
}
//echo "sleeping\n";
sleep(1);
}
$total_steps = get_total_steps("cmd_variables");
$disk_space = calc_est_size(
"lammps_script", "structure_file", "cmd_variables", $test_steps
);
$total_cpu = $total_steps*$avg_cpu;
return array($test_result, $total_cpu, $disk_space);
}
function get_total_steps($cmd_file) {
$fd = fopen($cmd_file,"r");
if (!$fd) {
echo "can not open file $cmd_file\n";
exit(-1);
}
$this_loopno = 1;
$this_looprun = 1;
$total_steps=1;
while (!feof($fd)) {
$line = fgets($fd,4096);
if (preg_match("/loopnumber\s+\d+/", $line, $matches)
&& preg_match("/\d+/", $matches[0], $no)
) {
$this_loopno=$no[0];
}
if (preg_match("/looprun\s+\d+/", $line, $matches)
and preg_match("/\d+/", $matches[0], $no)
) {
$this_looprun=$no[0];
if($this_loopno*$this_looprun>$total_steps)$total_steps=$this_loopno*$this_looprun;
}
}
fclose($fd);
//$total_steps = $loopno*$looprun;
if($GLOBALS["debug"])print "total_steps = ".$total_steps."
";
return $total_steps;
}
function calc_step_cpu($filename) {
$fd = fopen("$filename", "r");
$start_line = "Step CPU ";
$start = 0;
$start_step = 1;
$cur_step = 1;
$avg_cpu = 0;
$test_steps = 0;
if (!$fd) {
echo "fail to open file log.1";
exit(-1);
}
$count = 0;
while (!feof($fd)) {
$line = fgets($fd,4096);
if (preg_match('/^Step\s+CPU/',$line)) {
//echo $line."\n";
$start = 1;
continue;
}
if (!$start) continue;
$arr = preg_split("/\s+/", $line);
//print_r($arr);
if (count($arr) <=6 || !is_numeric($arr[1])) {
continue;
}
$step = (int)$arr[1];
$cpu = (float)$arr[2];
//echo "step=".$step." cpu=".$cpu."\n";
if ($cpu==0) {
$count=0;
$start_step = $step;
} else {
$count+=1;
if($GLOBALS["debug"])echo "step=".$step." cpu=".$cpu."count=".$count."
";
if($count >= 10) {
$end_step = $step;
$steps = $end_step-$start_step;
$avg_cpu = $cpu/$steps;
#$avg_cpu = $cpu/$count;
if ($GLOBALS["debug"]){
echo "test steps is ".$steps."
";
echo "avg_cpu is ".$avg_cpu."
";
}
$test_steps = $steps;
break;
}
}
}
return array($avg_cpu,$test_steps);
}
function calc_est_size($lammps_script, $structure_file, $cmd_file,$test_steps){
$dump_types = 0;
$fd = fopen($lammps_script,"r");
if (!$fd){
echo "can not open file $lammps_script\n";
exit(-1);
}
while (!feof($fd)){
$line = fgets($fd, 4096);
//if (preg_match("/^\s*dump/", $line)
// and preg_match_all("/dump\S+\.\w{3}/", $line, $matches, PREG_PATTERN_ORDER))
if(preg_match("/^\s*dump\s+(\d)\s+/", $line,$matches))
{
if($GLOBALS["debug"]){print "matches=";print_r($matches);}
$dump_types=(int)$matches[1];
break;
}
}
fclose($fd);
if($GLOBALS["debug"])print "dump_types= ".$dump_types."
";
$structure_file_size = filesize($structure_file);
$fd = fopen($cmd_file,"r");
if (!$fd){
echo "can not open file $cmd_file\n";
exit(-1);
}
if($GLOBALS["debug"]) print "structure_file_size=".$structure_file_size."
";
$loopno=1;
$looprun=1;
while (!feof($fd)){
$line = fgets($fd,4096);
if(preg_match("/loopnumber\s+\d+/", $line, $matches)){
if(preg_match("/\d+/", $matches[0], $no)){
//$loopno=$no[0];
if($no[0]>$loopno)$loopno=$no[0];
}
}
if (preg_match("/looprun\s+\d+/", $line, $matches) and preg_match("/\d+/", $matches[0], $no)) {
if($no[0]>$looprun)$looprun=$no[0];
}
}
fclose($fd);
if($GLOBALS["debug"]){
print "max loopno(number of loops to run)=".$loopno."
";
print "max looprun(steps for each loop)=".$looprun."
";
}
//$est_size = $loopno*$structure_file_size*0.8*$dump_types;
$test_log_size = filesize("log.1");
$log_size1 = ceil($looprun/$test_steps)*$test_log_size;
$log_size = $loopno*$log_size1;
$dump_files = glob("dump1*");
$test_dump_file = $dump_files[0];
$test_dump_size = filesize($test_dump_file);
$dump_size1 = $test_dump_size+0.5*$test_dump_size*ceil(($looprun-$test_steps)/$test_steps);
$dump_size = $loopno*$dump_size1*$dump_types;
$app_fixed_size = 5e7;
$est_size = $log_size+$dump_size+$app_fixed_size;
if($GLOBALS["debug"]){
print "test_steps=".$test_steps."
";
print "test_log_size=".$test_log_size."
";
print "log_size1=".$log_size1."
";
print "log_size=".$log_size."
";
print "test_dump_size=".$test_dump_size."
";
print "dump_size1=".$dump_size1."
";
print "dump_size=".$dump_size."
";
print "est_size=".$est_size."
";
}
//$est_size = $loopno*$structure_file_size*$dump_types;
return $est_size;
}
function area_select() {
return "
";
}
function show_submit_form($user) {
page_head("Submit LAMMPS jobs");
echo "
File sandbox
";
page_tail();
}
// verify that an input file exists in sandbox, and return its physical path
//
function get_file_path($user, $name) {
$fname = get_str($name);
// verify that the files exist in sandbox
//
$sbdir = sandbox_dir($user);
list($error, $size, $md5) = sandbox_parse_link_file("$sbdir/$fname");
if ($error) error_page("no $name file");
return sandbox_physical_path($user, $md5);
}
function project_flops() {
$x = BoincUser::sum("expavg_credit");
if ($x == 0) $x = 200;
$y = 1e9*$x/200;
return $y;
}
// Estimate how long a batch will take.
// Let N = # jobs, M = # hosts
// If N < M we can start all the jobs more or less now,
// so let T = F/H, where H is the median FLOPS of the hosts.
// If N > M we'll have to do the jobs in stages,
// so let T = ceil(N/M)*F/H.
//
// Note: these are both extremely optimistic estimates
//
function estimated_makespan($njobs, $flops_per_job) {
$nhosts = BoincHost::count("expavg_credit > 1");
if ($nhosts < 10) {
$median_flops = 2e9;
} else {
$n = (int)($nhosts/2);
$hs = BoincHost::enum("expavg_credit>1 order by p_fpops limit $n,1");
$h = $hs[0];
$median_flops = $h->p_fpops;
}
if ($njobs < $nhosts) {
return $flops_per_job/$median_flops;
} else {
$k = (int)(($njobs+$nhosts-1)/$nhosts);
return $k*$flops_per_job/$median_flops;
}
}
function prepare_batch($user) {
$structure_file_path = get_file_path($user, 'structure_file');
$command_file_path = get_file_path($user, 'lammps_script');
$cmdline_file_path = get_file_path($user, 'cmdline_file');
$pot_files_path = get_file_path($user, 'zip');
$info = new StdClass;
$info->structure_file_path = $structure_file_path;
$info->command_file_path = $command_file_path;
$info->cmdline_file_path = $cmdline_file_path;
$info->pot_files_path = $pot_files_path;
$info->area = get_str("area");
// get the directory in which to run the test,
// clear it out,
// and set up links to the input files
//
$test_dir = "../../lammps_test/$user->id";
//echo "test_dir is ".$test_dir;
if (!is_dir($test_dir)) {
mkdir($test_dir);
}
$old_dir = getcwd();
if (!chdir($test_dir)) {
error_page("Can't chdir");
}
system("rm *");
symlink($structure_file_path, "structure_file");
symlink($command_file_path, "lammps_script");
symlink($cmdline_file_path, "cmd_variables");
symlink($pot_files_path, "pot_files");
list($error, $est_cpu_time, $disk) = lammps_est();
if ($GLOBALS["debug"]) {
print "est_cpu_time is ".$est_cpu_time."
";
}
if ($error==0) {
$err_msgs=file("output");
$err="Your test job failed
Please refer to the following Error Message:
";
foreach($err_msgs as $line){
$err=$err.$line."
";
}
$err=$err."
File_Sandbox "; error_page($err); } system("rm *"); $info->rsc_fpops_est = $est_cpu_time * 1.5e9; $info->rsc_fpops_bound = $info->rsc_fpops_est * 20; if ($disk==0){ $info->rsc_disk_bound=1000000; } else{ $info->rsc_disk_bound = $disk; } $tmpfile = tempnam("/tmp", "lammps_"); file_put_contents($tmpfile, serialize($info)); // get the # of jobs // $njobs = count(file($cmdline_file_path)); $secs_est = estimated_makespan($njobs, $info->rsc_fpops_est); if($GLOBALS["debug"])echo "secs_est is $secs_est\n"; //assume the server's flops is 1.5G and the average client's flops is 1G $hrs_est = number_format($secs_est*1.5/60, 2); //$hrs_est = number_format($secs_est, 2); $client_mb = number_format($info->rsc_disk_bound/1e6, 1); $server_mb = number_format($njobs*$info->rsc_disk_bound/1e6, 1); chdir($old_dir); page_head("Batch prepared"); echo " Your batch has $njobs jobs.
Estimated time to completion: $hrs_est Minutes.
Estimated client disk usage: $client_mb MB
Estimated server disk usage: $server_mb MB
";
show_button("lammps.php?action=submit&tmpfile=$tmpfile", "Submit Batch");
page_tail();
}
function submit_job($app, $batch_id, $info, $cmdline, $i) {
$client_disk=$info->rsc_disk_bound*2;
if($client_disk<500000000) $client_disk=500000000;
$cmd = "cd ../..; ./bin/create_work --appname $app->name --batch $batch_id --rsc_fpops_est $info->rsc_fpops_est --rsc_fpops_bound $info->rsc_fpops_bound --rsc_disk_bound $client_disk";
if ($cmdline) {
$cmd .= " --command_line \"$cmdline\"";
}
$cmd .= " --wu_name batch_".$batch_id."_".$i;
$cmd .= " ".basename($info->structure_file_path);
$cmd .= " ".basename($info->command_file_path);
$cmd .= " ".basename($info->pot_files_path);
//echo "
$cmd\n";
system($cmd, $ret);
if ($ret === FALSE) {
error_page("can't create job");
} else {
header('Location: submit.php');
}
}
function submit_batch($user, $app) {
$tmpfile = get_str('tmpfile');
$x = file_get_contents("$tmpfile");
$info = unserialize($x);
$njobs=0;
$cmdlines = file($info->cmdline_file_path);
foreach ($cmdlines as $cmdline){
if (preg_match("/^\s*-var/", $cmdline)) {
$njobs++;
}
}
$now = time();
$batch_name = $info->area."_".date("Y-M-d D H:i:s");
$batch_id = BoincBatch::insert(
"(user_id, create_time, njobs, name, app_id, state) values ($user->id, $now, $njobs, '$batch_name', $app->id, ".BATCH_STATE_IN_PROGRESS.")"
);
// $batch_id=99;
$i = 0;
foreach ($cmdlines as $cmdline) {
if (preg_match("/^\s*-var/", $cmdline)){
submit_job($app, $batch_id, $info, $cmdline, $i);
$i++;
}
}
}
$user = get_logged_in_user();
$user_submit = BoincUserSubmit::lookup_userid($user->id);
if (!$user_submit) error_page("no submit access");
$app = BoincApp::lookup("name='lammps'");
if (!$app) error_page("no lammps app");
if (!$user_submit->submit_all) {
$usa = BoincUserSubmitApp::lookup("user_id=$user->id and app_id=$app->id");
if (!$usa) {
error_page("no submit access");
}
}
$action = get_str('action', true);
switch ($action) {
case '': show_submit_form($user); break;
case 'prepare': prepare_batch($user); break;
case 'submit': submit_batch($user, $app); break;
default: error_page("no such action $action");
}
?>