RUSH RENDER QUEUE
(C) Copyright 1995,2000 Greg Ercolano. All rights reserved.
V 102.40f 01/23/03
Strikeout text indicates features not yet implemented

  Submit Scripts  
 Template Submit Scripts
    In order to submit a job, you need both a submit script and render script. Both can be created quickly from scratch using the stock templates. A template submit script can be created quickly via:
    	      rush -tss > submit-script 
    	
    Here's a template submit script written in CSH:

      Csh Template Script
      #!/bin/csh -f
      
      #
      #  S U B M I T
      #
      
      source $RUSH_DIR/etc/.submit
      rush -submit << EOF
          title       SHOW/SHOT
          ram         250
          frames      1-100
          logdir      $cwd/logs     # "-" to disable
          command     $cwd/render-script
          autodump    done          # off, done, donefail
          cpus        vaio=1@100
      
          # Optional
          #donemail   you@foo.com   # "-" to disable
          #notes      This is a test
          #state      Pause
          #logflags   keepall
          #frames     1-10=Hold:Hello_world
          #criteria   ( linux | irix | osf1 )
      EOF
      
      exit $status
              

    Submit scripts don't have to be written as csh scripts. Any language that can pipe text into a command can be used to submit jobs. The following shows a template submit script written in Perl:

      Perl Template Submit
      #!/usr/bin/perl
      
      my $me   = `logname`; chomp($me);
      my $pwd  = `pwd`;     chomp($pwd);
      
      open(SUBMIT, "|rush -submit");
      print SUBMIT <<"EOF";
          title      mytest
          ram        10
          frames     1-100
          logdir     $pwd/logs
          command    $pwd/render-script 
          donemail   $me
          autodump   off
          criteria   ( linux | irix )
          cpus       +any=10\@100
      EOF
      close(SUBMIT);
      
      if ( $? >> 8 ) 
          { print STDERR "-- submit failed --\n"; exit(1); }
      
      exit(0);
              

    And the same program written in C:

      C Template Submit Script
      
      #include <stdio.h>
      #include <unistd.h>
      
      /* C EXAMPLE: Template Submit
       *
       *        UNIX COMPILE: 
       *             cc renderit.c -o renderit
       *
       *     WINDOWS COMPILE:
       *             vcvars32
       *             cl renderit.c
       */
      
      #ifdef _WIN32
      #include <direct.h>
      #define popen  		_popen 
      #define pclose 		_pclose 
      #endif
      
      int main(int argc, char *argv[])
      {
          char *me = getlogin();
          char cwd[1024]; getcwd(cwd, 1023);
      
          if ( ( fp = popen("rush -submit", "w") ) == NULL )
      	{ perror("couldn't popen(rush -submit)"); exit(1); }
      
          fprintf(fp, "    title      mytest\n"
                      "    ram        10\n"
                      "    frames     1-100\n"
                      "    logdir     $pwd/logs\n"
                      "    command    $pwd/renderit\n"
                      "    donemail   $me\n"
                      "    autodump   off\n"
                      "    criteria   ( linux | irix )\n"
                      "    cpus       +any=10@100\n");
      
          if ( pclose(fp) != 0 )
              { return(1); }
      
          return(0);
      }
              




 Perl: Submit Script, Read Back Jobid

    Here's a perl script that submits a sleep job, and parses back the jobid into a variable, which the perl script can then use for other purposes.

      Perl Submit and Read Back Jobid
      #!/usr/bin/perl
      
      # Create rush submit file
      my $tmp = "/tmp/.submit.$$";
      unless ( open ( SUBMIT, ">$tmp" ) ) 
          { print "open(>$tmp): $!\n"; exit(1); }
      
      print SUBMIT <<"EOF";
          title   SHOW/SHOT
          frames  1-10
          command sleep 30
          cpus    +any=1
      EOF
      
      unless ( close( SUBMIT ) )
          { print "close($tmp): $!\n"; exit(1); }
      
      # Submit the job, parse out jobid
      my $out = `rush -submit < $tmp`; unlink ( $tmp );
      if ( $out =~ /RUSH_JOBID (\S+)/ ) { $ENV{RUSH_JOBID} = $1; }
      else { print STDERR "$out\nSubmit failed.\n"; exit(1); }
      
      print "RUSH_JOBID IS NOW $ENV{RUSH_JOBID}\n";
      exit(0);
              




    Here's a simple C program that submits a sleep job.

      C Programming Example: Simple Submit
      #include <stdio.h>
      main()
      {
          FILE *fp;
          if ( ( fp = fopen("my-submit", "w") ) == NULL )
              { perror("my-submit"); exit(1); }
          fprintf(fp, "title      TEST\n"
                      "ram        1\n"
                      "frames     1-10\n"
                      "command    rush -sleep 300\n"
                      "cpus       +any=10\n");
          fclose(fp);
          system("rush -submit < my-submit");
      }
              




    Here's a more complex C program that acts as both a submit and render script, using recursion to invoke itself. It also uses pipes to prevent creating the temporary file used to submit the job in the previous example. Note that it's critical to invoke this program with an absolute path so the program can invoke itself correctly from other machines.

    There are three versions of this program:

      C Programming Example: Submit and Render
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <errno.h>
      
      /* C EXAMPLE: Submit and Render
       *
       * This program acts as both a submit and render script.
       * It is important to invoke this program initially with an absolute path,
       * so the program can call itself correctly from other machines.
       *
       *        UNIX COMPILE: 
       *             cc filename.c -o filename
       *
       *     WINDOWS COMPILE:
       *             vcvars32
       *             cl filename.c
       */
      #ifdef _WIN32
      #include <direct.h>
      #define popen  		_popen 
      #define pclose 		_pclose 
      #define mkdir(a,b)	_mkdir(a)
      #endif
      
      int main(int argc, char **argv)
      {
          if ( argc >= 2 && strcmp(argv[1], "-render") == 0 )
          {
      	/* CALLED AS A RENDER SCRIPT? 
      	 * Invoke maya, return exit code.
      	 */
      	int t;
      	char cmd[4096];
      
      	sprintf(cmd, "mayabatch -render -s %s -e %s",
      	    getenv("RUSH_FRAME"),
      	    getenv("RUSH_FRAME"));
      	for ( t=2; t<argc; t++ )
      	    { strcat(cmd, " "); strcat(cmd, argv[t]); }
      
      	fprintf(stderr, "Executing: %s\n", cmd);
      	t = system(cmd) >> 8;
      	if ( t != 0 )
      	    { fprintf(stderr, "MAYA FAILED: EXIT CODE=%d\n", t); exit(1); }
      
      	fprintf(stderr, "MAYA SUCCESS\n");
      	exit(0);
          }
          else
          {
      	/* CALLED AS A SUBMIT SCRIPT?
      	 * Then prompt for info, and submit the job
      	 */
      	FILE *fp;
      	char title[40];
      	char frames[40];
      	char scene[1024];
      	char cpus[1024];
      	char cmd[1024];
      	char logdir[1024];
      
      	fprintf(stderr, "  Enter title for job: "); 
      	fgets(title, sizeof(title)-1, stdin);
      	title[strlen(title)-1] = '\0';
      
      	fprintf(stderr, " Enter the scene file: "); 
      	fgets(scene, sizeof(scene)-1, stdin);
      	scene[strlen(scene)-1] = '\0';
      
      	fprintf(stderr, "Enter the frame range: "); 
      	fgets(frames, sizeof(frames)-1, stdin);
      	frames[strlen(frames)-1] = '\0';
      
      	fprintf(stderr, "       Enter the cpus: "); 
      	fgets(cpus, sizeof(cpus)-1, stdin);
      	cpus[strlen(cpus)-1] = '\0';
      
      	/* MAKE LOGDIR BASED ON TITLE OF JOB
      	 * There are cleaner ways to do this.
      	 */
       	{
      	    int oldmask = umask(0);
      	    sprintf(logdir, "//tahoe/net/tmp/%s", title);
      	    if ( mkdir(logdir, 0777) < 0 && errno != EEXIST )
      		{ perror(logdir); exit(1); }
      	    umask(oldmask);
      	}
      
      	/* SUBMIT THE JOB 
      	 * Feed the submit commands down a pipe.
      	 */
      	if ( ( fp = popen("rush -submit", "w") ) == NULL )
      	    { perror("couldn't popen(rush -submit)"); exit(1); }
      	fprintf(fp, "title   %s\n", title);
      	fprintf(fp, "ram     1\n");
      	fprintf(fp, "frames  %s\n", frames);
      	fprintf(fp, "logdir  %s\n", logdir);
      	fprintf(fp, "command %s -render %s\n", argv[0], scene);
      	fprintf(fp, "cpus    %s\n", cpus);
      	pclose(fp);
      
      	exit(0);
          }
          /*NOTREACHED*/
      }
              

      Perl: Submit and Render Script
      #!/usr/bin/perl
      
      # PERL EXAMPLE: Submit and Render
      #
      # This program acts as both a submit and render script.
      # It is important to invoke this program initially with an absolute path,
      # so the program can call itself correctly from other machines.
      #
      
      $|=1;
      if ( $ARGV[0] eq "-render" )
      {
          # CALLED AS A RENDER SCRIPT?
          # Invoke maya, return exit code.
          my $t;
          my $cmd = sprintf("mayabatch -render -s %s -e %s",
                             $ENV{RUSH_FRAME},
                             $ENV{RUSH_FRAME});
      
          for ( $t=1; $t<=$#ARGV; $t++ )
              { $cmd .= " $ARGV[$t]"; }
      
          print STDERR "Executing: $cmd\n";
          $t = system($cmd) >> 8;
          if ( $t != 0 )
              { print STDERR "MAYA FAILED: EXIT CODE=$t\n"; exit(1); }
      
          print STDERR "MAYA SUCCESS\n";
          exit(0);
      }
      else
      {
          # CALLED AS A SUBMIT SCRIPT?
          # Then prompt for info, and submit the job
      
          print STDERR "  Enter title for job: ";
          my $title = <STDIN>; chomp($title);
      
          print STDERR " Enter the scene file: ";
          my $scene = <STDIN>; chomp($scene);
      
          print STDERR "Enter the frame range: ";
          my $frames = <STDIN>; chomp($frames);
      
          print STDERR "       Enter the cpus: ";
          my $cpus = <STDIN>; chomp($cpus);
      
          # MAKE LOGDIR BASED ON TITLE OF JOB
          # There are cleaner ways to do this
          #
          my $logdir = sprintf("//tahoe/net/tmp/%s", $title);
          if ( ! -e $logdir )
          {
              my $oldmask = umask(0);
      	unless ( mkdir($logdir, 0777) )
      	    { print STDERR "$logdir: $!\n"; exit(1); }
              umask($oldmask);
          }
      
          # SUBMIT THE JOB
          # Feed the submit commands down a pipe.
          #
          open(SUBMIT, "|rush -submit");
          print SUBMIT <<"EOF";
          title      $title
          ram        1
          frames     $frames
          logdir     $logdir
          command    perl $0 -render $scene
          cpus       $cpus
      EOF
          close(SUBMIT);
      
          if ( $? >> 8 ) 
      	{ print STDERR "-- submit failed --\n"; exit(1); }
      
          exit(0);
      }
              

      CSH: Submit and Render Script
      #!/bin/csh -f
      
      # CSH EXAMPLE: Submit and Render
      #
      # This program acts as both a submit and render script.
      # It is important to invoke this program initially with an absolute path,
      # so the program can call itself correctly from other machines.
      #
      
      if ( "$1" == "-render" ) then
      
          # CALLED AS A RENDER SCRIPT?
          # Invoke maya, return exit code.
      
          set cmd = "mayabatch -render -s $RUSH_FRAME -e $RUSH_FRAME";
      
          shift
          set cmd = "$cmd $*:q"
      
          echo "Executing: $cmd"
          $cmd
          set err = $status
          if ( $err != 0 ) then
              echo "MAYA FAILED: EXIT CODE=$err\n"
      	exit 1
          endif
      
          echo "MAYA SUCCESS"
          exit 0
      else
          # CALLED AS A SUBMIT SCRIPT?
          # Then prompt for info, and submit the job
      
          echo -n "  Enter title for job: ";
          set title = "$<"
      
          echo " Enter the scene file: ";
          set scene = "$<"
      
          echo "Enter the frame range: ";
          set frames = "$<"
      
          echo "       Enter the cpus: ";
          set cpus = "$<"
      
          # MAKE LOGDIR BASED ON TITLE OF JOB
          # There are cleaner ways to do this
          #
          set logdir = "//tahoe/net/tmp/$title"
          if ( ! -e $logdir ) then
              umask 0
      	mkdir -m 0777 $logdir
      	if ( $status ) exit 1
          endif
      
          # SUBMIT THE JOB
          # Feed the submit commands down a pipe.
          #
          cat << EOF | rush -submit
          title      $title
          ram        1
          frames     $frames
          logdir     $logdir
          command    csh -f $0 -render $scene
          cpus       $cpus
      EOF
          exit $status
      endif
              

  Maya Submit/Render Script  

Maya Combo Submit/Render Scripts

These are simple examples of combination submit/render scripts; there's a Perl version, and a DOS batch version. Use either one; the perl version is more portable.

To keep the examples simple, there's no frame batching or any fancy stuff.

Simple PERL Maya Submit/Render Script

    PERL: Maya Submit / Render
    #!/usr/bin/perl
    
    # SIMPLE MAYA PERL SUBMIT EXAMPLE
    #     Shows the easiest way to make a self contained
    #     submit/render script.
    #
    
    $|=1;
    umask(0);
    
    # NEED ABSOULUTE PATH TO SELF
    my $self = $0;
    if ( $self !~ m%^[/\\]% && $self !~ m%^[a-zA-Z]:% )
        { my $pwd=`pwd`; chomp($pwd); $self = "$pwd/$0"; }
    
    # MAIN
    {
        if ( $#ARGV < 1 )
        {
    	print STDERR "USAGE\n".
    		     "    $0 scenefile framerange [imagedir]\n\n".
    		     "EXAMPLE\n".
    		     "    $self //tahoe/net/tmp/scenes/foo.ma 1-20,2\n\n";
    	exit(1);
        }
    
        # INVOKED AS A RENDER SCRIPT?
        #    Then rush is calling us to render a frame.
        #    Create maya command line and run it, checking for errors.
        #
        if ( $ARGV[0] eq "-render" )
        {
    	shift(@ARGV);
    	my ($scenefile,$imagedir) = @ARGV;
    	$imagedir = ( $imagedir eq "-" ) ? "" : "-rd $imagedir";
    
    	my $cmd = "render -s $ENV{RUSH_FRAME} -e $ENV{RUSH_FRAME} $imagedir $scenefile";
    
    	print "   SCENE=$scenefile\n".
                  "IMAGEDIR=$scenefile\n";
                  "   FRAME=$ENV{RUSH_PADFRAME}\n".
    	      "\n"
                  "Executing: $cmd\n";
    
    	my $exitcode = system($cmd) >> 8;
    
    	if ( $exitcode ) 
    	{
    	    print STDERR "MAYA FAILED: EXITCODE=$exitcode\n";
    	    exit(1);	# "Fail"
    	}
    
    	print STDERR "MAYA SUCCEEDED: EXITCODE=$exitcode\n"; 
    	exit(0);	# "Done"
        }
        else
        {
    	# INVOKED AS A SUBMIT SCRIPT?
    	#     Get args from command line, and submit to rush
    	#
    	my ($scenefile,$frames,$imagedir) = @ARGV;
    	if ( $imagedir eq "" ) 
    	    { $imagedir = "-"; }
    
    	open(SUBMIT, "|rush -submit");
    	print SUBMIT <<"EOF";
    	    title      MAYA
    	    ram        10
    	    frames     $frames
    	    logdir     $scenefile.log/%s
    	    command    perl $self -render $scenefile $imagedir
    	    cpus       +any=10\@100
    EOF
    	close(SUBMIT);
    	if ( $? >> 8 ) 
    	    { print STDERR "-- submit failed --\n"; exit(1); }
    
    	exit(0);
        }
        #NOTREACHED
    }
            

Simple DOS Maya Submit/Render Script

Here's a similar script written as a DOS batch script. Because DOS is very limited in its string manipulation ability (it practically has none), this script is not as featured as the Perl version.

    DOS: Maya Submit / Render
    @echo off
    
    REM ###
    REM ### DOS BATCH -- MAYA SUBMIT/RENDER SCRIPT
    REM ###
    
    REM ### USER SHOULD CHANGE THESE!!
    REM ###    Use UNC style absolute pathnames with front "/" slashes.
    REM ###
    set   MAYASCENE=//tahoe/net/tmp/scenes/foo.mb
    set MAYAPROJECT=//tahoe/net/tmp
    set  MAYALOGDIR=//tahoe/net/tmp/scenes/foo.mb.log
    set    MAYACPUS=geneva=2@100
    
    
    if "%1"=="-render" goto RENDER
    
    REM ######################
    REM ### SUBMIT SECTION ###
    REM ######################
    :SUBMIT
    set TMPDIR=c:\temp
    set SUBMIT=c:\temp\$$$.bat
    set SELF=%0
    set SELF=%SELF:\=/%
    (
    echo    title      TEST
    echo    ram        1
    echo    frames     1-10
    echo    logdir     %MAYALOGDIR%
    echo    command    cmd /c %SELF% -render
    echo    cpus       %MAYACPUS%
    ) | rush -submit > %SUBMIT%
    if %ERRORLEVEL% GEQ 1 goto DONE
    call %SUBMIT%
    del %SUBMIT%
    echo RUSH_JOBID is %RUSH_JOBID%
    start /b irush
    goto DONE
    
    
    REM ######################
    REM ### RENDER SECTION ###
    REM ######################
    :RENDER
    echo MAYA SCENE=%MAYASCENE%
    echo MAYA PROJECT=%MAYAPROJECT%
    @echo on
    @echo EXECUTING MAYA:
    mayabatch -render -verbose 1 -proj %MAYAPROJECT% -s %RUSH_FRAME% -e %RUSH_FRAME% -b 1 %MAYASCENE%
    @set ERR=%ERRORLEVEL%
    @echo off
    if %ERR% EQU 128 goto REQUEUE128
    if %ERR% GTR 0   goto FAIL
    echo --- MAYA SUCCEEDS: EXITCODE=%ERR%
    exit 0
    
    :FAIL
    echo --- MAYA FAILED: EXITCODE=%ERR%
    exit 1
    
    
    :REQUEUE128
    echo --- MAYA INDICATES LICENSE ERROR (EXIT 128)
    echo --- ADDING THIS MACHINE AS NEVERHOST AND REQUEING
    rush -fu an %RUSH_HOSTNAME%
    exit 2
    
    :DONE