Issues (1963)

html/user/lammps.php (18 issues)

1
<?php
2
3
// script for submitting batches of LAMMPS jobs
4
//
5
// When a batch is submitted, this script runs the first job
6
// until 1 time step is completed;
7
// this verifies that the input files are OK and gives us
8
// an estimate of the FLOPS needed for the batch.
9
//
10
// These test executions are done in the directory
11
// project/lammps_test/USERID.
12
// We assume that lammps_test exists and contains the LAMMPS executable
13
14
require_once("../inc/util.inc");
15
require_once("../inc/submit_db.inc");
16
require_once("../inc/sandbox.inc");
17
18
display_errors();
19
20
$debug=0;
21
22
// test a LAMMPS job
23
//
24
// the current directory must contain
25
//      structure_file
26
//      lammps_script
27
//      cmd_variables
28
//      pot_files (zipped potential files)
29
//
30
// output: success flag, CPU time per step, est. disk usage per job
31
//
32
function terminate_job($p) {
33
    $pstatus=proc_get_status($p);
34
    $ppid=$pstatus['pid'];
35
    $ret=`ps -o pid --no-heading --ppid $ppid`;
36
    //echo "parent pid is $ppid\nterninate it\n";
37
     proc_terminate($p);
38
    // echo "child process is $ret\n";
39
    $pids=preg_split('/\s+/',$ret);
40
    foreach($pids as $pid){
41
        if(is_numeric($pid)){
42
            if($GLOBALS["debug"])echo "killing child process $pid\n";
43
            posix_kill($pid,9);
0 ignored issues
show
$pid of type string is incompatible with the type integer expected by parameter $process_id of posix_kill(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

43
            posix_kill(/** @scrutinizer ignore-type */ $pid,9);
Loading history...
44
        }
45
    }
46
}
47
48
function lammps_est() {
49
    $avg_cpu = 0;
50
    $test_result = 0;
51
    $descs = array();
52
    $pipes = array();
53
    $options = file("cmd_variables");
54
    $options[0] = chop($options[0],"\n");
55
    $cmd = "../lmp_linux ".$options[0]."&>output";
56
    if ($GLOBALS["debug"]) echo $cmd."<br>";
57
    system("unzip pot_files >/dev/null");
58
    $stime = time();
59
    $p = proc_open("$cmd", $descs, $pipes);
60
    while (1) {
61
        $ctime=time();
62
        if($ctime-$stime >=2 and ! file_exists("log.1")){
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
63
           if($GLOBALS["debug"]) echo "time out "."<br>";
64
           terminate_job($p);
65
           break;
66
        }
67
        if (file_exists("log.1")) {
68
            list($avg_cpu, $test_steps) = calc_step_cpu("log.1");
0 ignored issues
show
Are you sure the assignment to list($avg_cpu, $test_steps) is correct as calc_step_cpu('log.1') seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
69
            if ($avg_cpu != 0) {
70
                if($GLOBALS["debug"])echo "avg_cpu is ".$avg_cpu."<br>";
71
                terminate_job($p);
72
                $test_result = 1;
73
                break;
74
            }
75
        }
76
        //echo "sleeping\n";
77
        sleep(1);
78
    }
79
80
    $total_steps = get_total_steps("cmd_variables");
0 ignored issues
show
Are you sure the assignment to $total_steps is correct as get_total_steps('cmd_variables') seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
81
    $disk_space = calc_est_size(
82
        "lammps_script", "structure_file", "cmd_variables", $test_steps
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $test_steps does not seem to be defined for all execution paths leading up to this point.
Loading history...
83
    );
84
    $total_cpu = $total_steps*$avg_cpu;
85
    return array($test_result, $total_cpu, $disk_space);
86
}
87
88
function get_total_steps($cmd_file) {
89
    $fd = fopen($cmd_file,"r");
90
    if (!$fd) {
0 ignored issues
show
$fd is of type resource, thus it always evaluated to false.
Loading history...
91
        echo "can not open file $cmd_file\n";
92
        exit(-1);
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
93
    }
94
    $this_loopno = 1;
95
    $this_looprun = 1;
96
    $total_steps=1;
97
    while (!feof($fd)) {
98
        $line = fgets($fd,4096);
99
        if (preg_match("/loopnumber\s+\d+/", $line, $matches)
100
            && preg_match("/\d+/", $matches[0], $no)
101
        ) {
102
            $this_loopno=$no[0];
103
        }
104
        if (preg_match("/looprun\s+\d+/", $line, $matches)
105
            and preg_match("/\d+/", $matches[0], $no)
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
106
        ) {
107
            $this_looprun=$no[0];
108
            if($this_loopno*$this_looprun>$total_steps)$total_steps=$this_loopno*$this_looprun;
109
        }
110
111
    }
112
    fclose($fd);
113
    //$total_steps = $loopno*$looprun;
114
     if($GLOBALS["debug"])print "total_steps = ".$total_steps."<br>";
115
    return $total_steps;
116
}
117
118
function calc_step_cpu($filename) {
119
    $fd = fopen("$filename", "r");
120
    $start_line = "Step CPU ";
121
    $start = 0;
122
    $start_step = 1;
123
    $cur_step = 1;
124
    $avg_cpu = 0;
125
    $test_steps = 0;
126
    if (!$fd) {
0 ignored issues
show
$fd is of type resource, thus it always evaluated to false.
Loading history...
127
        echo "fail to open file log.1";
128
        exit(-1);
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
129
    }
130
    $count = 0;
131
    while (!feof($fd)) {
132
        $line = fgets($fd,4096);
133
        if (preg_match('/^Step\s+CPU/',$line)) {
134
            //echo $line."\n";
135
            $start = 1;
136
            continue;
137
        }
138
        if (!$start) continue;
139
        $arr = preg_split("/\s+/", $line);
140
        //print_r($arr);
141
142
        if (count($arr) <=6 || !is_numeric($arr[1])) {
143
            continue;
144
        }
145
        $step = (int)$arr[1];
146
        $cpu = (float)$arr[2];
147
        //echo "step=".$step." cpu=".$cpu."\n";
148
        if ($cpu==0) {
149
           $count=0;
150
           $start_step = $step;
151
        } else {
152
            $count+=1;
153
            if($GLOBALS["debug"])echo "step=".$step." cpu=".$cpu."count=".$count."<br>";
154
           if($count >= 10) {
155
                $end_step = $step;
156
                $steps = $end_step-$start_step;
157
                $avg_cpu = $cpu/$steps;
158
                #$avg_cpu = $cpu/$count;
0 ignored issues
show
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
159
                if ($GLOBALS["debug"]){
160
                    echo "test steps is ".$steps."<br>";
161
                    echo "avg_cpu is ".$avg_cpu."<br>";
162
                }
163
                $test_steps = $steps;
164
                break;
165
            }
166
        }
167
    }
168
    return array($avg_cpu,$test_steps);
169
}
170
171
function calc_est_size($lammps_script, $structure_file, $cmd_file,$test_steps){
172
    $dump_types = 0;
173
    $fd = fopen($lammps_script,"r");
174
    if (!$fd){
0 ignored issues
show
$fd is of type resource, thus it always evaluated to false.
Loading history...
175
        echo "can not open file $lammps_script\n";
176
        exit(-1);
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
177
    }
178
    while (!feof($fd)){
179
        $line = fgets($fd, 4096);
180
        //if (preg_match("/^\s*dump/", $line)
181
        //    and preg_match_all("/dump\S+\.\w{3}/", $line, $matches, PREG_PATTERN_ORDER))
182
183
        if(preg_match("/^\s*dump\s+(\d)\s+/", $line,$matches))
184
        {
185
             if($GLOBALS["debug"]){print "matches=";print_r($matches);}
186
187
            $dump_types=(int)$matches[1];
188
            break;
189
        }
190
    }
191
    fclose($fd);
192
    if($GLOBALS["debug"])print "dump_types= ".$dump_types."<br>";
193
194
    $structure_file_size = filesize($structure_file);
195
    $fd = fopen($cmd_file,"r");
196
    if (!$fd){
197
        echo "can not open file $cmd_file\n";
198
        exit(-1);
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
199
    }
200
     if($GLOBALS["debug"]) print "structure_file_size=".$structure_file_size."<br>";
201
202
    $loopno=1;
203
    $looprun=1;
204
    while (!feof($fd)){
205
        $line = fgets($fd,4096);
206
        if(preg_match("/loopnumber\s+\d+/", $line, $matches)){
207
            if(preg_match("/\d+/", $matches[0], $no)){
208
                //$loopno=$no[0];
209
                if($no[0]>$loopno)$loopno=$no[0];
210
            }
211
        }
212
        if (preg_match("/looprun\s+\d+/", $line, $matches) and preg_match("/\d+/", $matches[0], $no)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
213
            if($no[0]>$looprun)$looprun=$no[0];
214
        }
215
    }
216
    fclose($fd);
217
    if($GLOBALS["debug"]){
218
         print "max loopno(number of loops to run)=".$loopno."<br>";
219
         print "max looprun(steps for each loop)=".$looprun."<br>";
220
    }
221
    //$est_size = $loopno*$structure_file_size*0.8*$dump_types;
222
    $test_log_size = filesize("log.1");
223
    $log_size1 = ceil($looprun/$test_steps)*$test_log_size;
224
    $log_size = $loopno*$log_size1;
225
    $dump_files = glob("dump1*");
226
    $test_dump_file = $dump_files[0];
227
    $test_dump_size = filesize($test_dump_file);
228
    $dump_size1 = $test_dump_size+0.5*$test_dump_size*ceil(($looprun-$test_steps)/$test_steps);
229
    $dump_size = $loopno*$dump_size1*$dump_types;
230
    $app_fixed_size = 5e7;
231
    $est_size = $log_size+$dump_size+$app_fixed_size;
232
233
    if($GLOBALS["debug"]){
234
        print "test_steps=".$test_steps."<br>";
235
        print "test_log_size=".$test_log_size."<br>";
236
        print "log_size1=".$log_size1."<br>";
237
        print "log_size=".$log_size."<br>";
238
        print "test_dump_size=".$test_dump_size."<br>";
239
        print "dump_size1=".$dump_size1."<br>";
240
        print "dump_size=".$dump_size."<br>";
241
        print "est_size=".$est_size."<br>";
242
    }
243
    //$est_size = $loopno*$structure_file_size*$dump_types;
244
    return $est_size;
245
}
246
247
248
function area_select() {
249
    return "
250
        <select name=area>
251
        <option value=\"Air filtration\">Air filtration</option>
252
        <option value=\"Water filtration\">Water filtration</option>
253
        <option value=\"Ultra-low friction\">Ultra-low friction</option>
254
        </select>
255
    ";
256
}
257
258
function show_submit_form($user) {
259
    page_head("Submit LAMMPS jobs");
260
    echo "
261
        <form action=lammps.php>
262
        <input type=hidden name=action value=prepare>
263
    ";
264
    start_table();
265
    row2("<strong>structure_file</strong><br><p class=\"text-muted\">structure_file*</p>", sandbox_file_select($user, "structure_file"));
266
    row2("<strong>lammps_script</strong><br><p class=\"text-muted\">lammps_script*</p>", sandbox_file_select($user, "lammps_script"));
267
    row2("<strong>cmdline_file</strong><br><p class=\"text-muted\">cmdline_file* (List of command lines, one per job )</p>", sandbox_file_select($user, "cmdline_file"));
268
    row2("<strong>pot.zip</strong><br><p class=\"text-muted\">*.zip ( Zipped Potential files )</span>", sandbox_file_select($user, "zip"));
269
    row2("<strong>Area</strong>", area_select());
270
    row2("", "<input class=\"btn btn-default\" type=submit value=Prepare>");
271
    end_table();
272
    echo "</form>
273
        <p>
274
        <a href=sandbox.php><strong> File sandbox </strong></a>
275
    ";
276
277
    page_tail();
278
}
279
280
// verify that an input file exists in sandbox, and return its physical path
281
//
282
function get_file_path($user, $name) {
283
    $fname = get_str($name);
284
285
    // verify that the files exist in sandbox
286
    //
287
    $sbdir = sandbox_dir($user);
288
    list($error, $size, $md5) = sandbox_parse_link_file("$sbdir/$fname");
289
    if ($error) error_page("no $name file");
290
291
    return sandbox_physical_path($user, $md5);
292
}
293
294
function project_flops() {
295
    $x = BoincUser::sum("expavg_credit");
296
    if ($x == 0) $x = 200;
297
    $y = 1e9*$x/200;
298
    return $y;
299
}
300
301
// Estimate how long a batch will take.
302
// Let N = # jobs, M = # hosts
303
// If N < M we can start all the jobs more or less now,
304
// so let T = F/H, where H is the median FLOPS of the hosts.
305
// If N > M we'll have to do the jobs in stages,
306
// so let T = ceil(N/M)*F/H.
307
//
308
// Note: these are both extremely optimistic estimates
309
//
310
function estimated_makespan($njobs, $flops_per_job) {
311
    $nhosts = BoincHost::count("expavg_credit > 1");
312
    if ($nhosts < 10) {
313
        $median_flops = 2e9;
314
    } else {
315
        $n = (int)($nhosts/2);
316
        $hs = BoincHost::enum("expavg_credit>1 order by p_fpops limit $n,1");
317
        $h = $hs[0];
318
        $median_flops = $h->p_fpops;
319
    }
320
321
    if ($njobs < $nhosts) {
322
        return $flops_per_job/$median_flops;
323
    } else {
324
        $k = (int)(($njobs+$nhosts-1)/$nhosts);
325
        return $k*$flops_per_job/$median_flops;
326
    }
327
}
328
329
function prepare_batch($user) {
330
    $structure_file_path = get_file_path($user, 'structure_file');
331
    $command_file_path = get_file_path($user, 'lammps_script');
332
    $cmdline_file_path = get_file_path($user, 'cmdline_file');
333
    $pot_files_path = get_file_path($user, 'zip');
334
335
    $info = new StdClass;
336
    $info->structure_file_path = $structure_file_path;
337
    $info->command_file_path = $command_file_path;
338
    $info->cmdline_file_path = $cmdline_file_path;
339
    $info->pot_files_path = $pot_files_path;
340
    $info->area = get_str("area");
341
342
    // get the directory in which to run the test,
343
    // clear it out,
344
    // and set up links to the input files
345
    //
346
    $test_dir = "../../lammps_test/$user->id";
347
    //echo "test_dir is ".$test_dir;
348
    if (!is_dir($test_dir)) {
349
        mkdir($test_dir);
350
    }
351
    $old_dir = getcwd();
352
    if (!chdir($test_dir)) {
353
        error_page("Can't chdir");
354
    }
355
    system("rm *");
356
    symlink($structure_file_path, "structure_file");
357
    symlink($command_file_path, "lammps_script");
358
    symlink($cmdline_file_path, "cmd_variables");
359
    symlink($pot_files_path, "pot_files");
360
    list($error, $est_cpu_time, $disk) = lammps_est();
361
    if ($GLOBALS["debug"]) {
362
        print "est_cpu_time is ".$est_cpu_time."<br>";
363
    }
364
    if ($error==0) {
365
        $err_msgs=file("output");
366
        $err="Your test job <strong>failed</strong>
367
            <br>Please refer to the following Error Message:<br><p>
368
        ";
369
        foreach($err_msgs as $line){
370
             $err=$err.$line."<br>";
371
        }
372
        $err=$err." <p>
373
            <a href=sandbox.php><strong> File_Sandbox </strong></a>
374
        ";
375
        error_page($err);
376
    }
377
378
    system("rm *");
379
    $info->rsc_fpops_est = $est_cpu_time * 1.5e9;
380
    $info->rsc_fpops_bound = $info->rsc_fpops_est * 20;
381
382
    if ($disk==0){
383
        $info->rsc_disk_bound=1000000;
384
    } else{
385
        $info->rsc_disk_bound = $disk;
386
    }
387
388
    $tmpfile = tempnam("/tmp", "lammps_");
389
    file_put_contents($tmpfile, serialize($info));
390
391
    // get the # of jobs
392
    //
393
    $njobs = count(file($cmdline_file_path));
394
    $secs_est = estimated_makespan($njobs, $info->rsc_fpops_est);
395
     if($GLOBALS["debug"])echo "secs_est is $secs_est\n";
396
    //assume the server's flops is 1.5G and the average client's flops is 1G
397
    $hrs_est = number_format($secs_est*1.5/60, 2);
398
    //$hrs_est = number_format($secs_est, 2);
399
    $client_mb = number_format($info->rsc_disk_bound/1e6, 1);
400
    $server_mb = number_format($njobs*$info->rsc_disk_bound/1e6, 1);
401
402
    chdir($old_dir);
403
    page_head("Batch prepared");
404
    echo "
405
        Your batch has $njobs jobs.
406
        <p>
407
        Estimated time to completion: $hrs_est Minutes.
408
        <p>
409
        Estimated client disk usage: $client_mb MB
410
        <p>
411
        Estimated server disk usage: $server_mb MB
412
        <p>
413
    ";
414
    show_button("lammps.php?action=submit&tmpfile=$tmpfile", "Submit Batch");
415
    page_tail();
416
}
417
418
function submit_job($app, $batch_id, $info, $cmdline, $i) {
419
    $client_disk=$info->rsc_disk_bound*2;
420
    if($client_disk<500000000) $client_disk=500000000;
421
    $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";
422
    if ($cmdline) {
423
        $cmd .= " --command_line \"$cmdline\"";
424
    }
425
    $cmd .= " --wu_name batch_".$batch_id."_".$i;
426
    $cmd .= " ".basename($info->structure_file_path);
427
    $cmd .= " ".basename($info->command_file_path);
428
    $cmd .= " ".basename($info->pot_files_path);
429
    //echo "<br> $cmd\n";
430
431
    system($cmd, $ret);
432
    if ($ret === FALSE) {
433
        error_page("can't create job");
434
    } else {
435
        header('Location: submit.php');
436
    }
437
}
438
439
function submit_batch($user, $app) {
440
    $tmpfile = get_str('tmpfile');
441
    $x = file_get_contents("$tmpfile");
442
    $info = unserialize($x);
443
444
    $njobs=0;
445
    $cmdlines = file($info->cmdline_file_path);
446
    foreach ($cmdlines as $cmdline){
447
        if (preg_match("/^\s*-var/", $cmdline)) {
448
            $njobs++;
449
        }
450
    }
451
452
    $now = time();
453
    $batch_name = $info->area."_".date("Y-M-d D H:i:s");
454
455
    $batch_id = BoincBatch::insert(
456
        "(user_id, create_time, njobs, name, app_id, state) values ($user->id, $now, $njobs, '$batch_name', $app->id, ".BATCH_STATE_IN_PROGRESS.")"
457
    );
458
//    $batch_id=99;
459
460
    $i = 0;
461
    foreach ($cmdlines as $cmdline) {
462
        if (preg_match("/^\s*-var/", $cmdline)){
463
            submit_job($app, $batch_id, $info, $cmdline, $i);
464
            $i++;
465
        }
466
    }
467
}
468
469
$user = get_logged_in_user();
0 ignored issues
show
Are you sure the assignment to $user is correct as get_logged_in_user() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
470
$user_submit = BoincUserSubmit::lookup_userid($user->id);
471
if (!$user_submit) error_page("no submit access");
472
$app = BoincApp::lookup("name='lammps'");
473
if (!$app) error_page("no lammps app");
474
475
if (!$user_submit->submit_all) {
476
    $usa = BoincUserSubmitApp::lookup("user_id=$user->id and app_id=$app->id");
477
    if (!$usa) {
478
        error_page("no submit access");
479
    }
480
}
481
482
$action = get_str('action', true);
483
switch ($action) {
484
case '': show_submit_form($user); break;
485
case 'prepare': prepare_batch($user); break;
486
case 'submit': submit_batch($user, $app); break;
487
default: error_page("no such action $action");
0 ignored issues
show
DEFAULT keyword must be indented 4 spaces from SWITCH keyword
Loading history...
DEFAULT case must have a breaking statement
Loading history...
488
}
489
?>
490