[[PageOutline]] = The BOINC Wrapper = Any existing application (or sequence of applications) can be run under BOINC using a '''wrapper''' program supplied by BOINC. The wrapper runs the applications as subprocesses, and handles all communication with the core client (e.g., to report CPU time and fraction done). [[Image(http://boinc.berkeley.edu/wrapper.png)]] The source code of wrapper is in [ExampleApps boinc/samples]. You can get pre-compiled versions here: * [http://boinc.berkeley.edu/dl/wrapper_25825_windows_intelx86.zip wrapper_25825_windows_intelx86.zip] * [http://boinc.berkeley.edu/dl/wrapper_25825_windows_x86_64.zip wrapper_25825_windows_x86_64.zip] * [http://boinc.berkeley.edu/dl/wrapper_25825_i686-pc-linux-gnu.zip wrapper_25825_i686-pc-linux-gnu.zip] * [http://boinc.berkeley.edu/dl/wrapper_25825_x86_64-pc-linux-gnu.zip wrapper_25825_x86_64-pc-linux-gnu.zip] * [http://boinc.berkeley.edu/dl/wrapper_25825_i686-apple-darwin.zip wrapper_25825_i686-apple-darwin.zip] * [http://boinc.berkeley.edu/dl/wrapper_25825_x86_64-apple-darwin.zip wrapper_25825_x86_64-apple-darwin.zip] == The job description file == The wrapper reads a file with [BoincFiles logical name] 'job.xml'. This file has the format: {{{ worker [ stdin_file ] [ stdout_file ] [ stderr_file ] [ --foo bar ] [ X ] [ filename ] [ filename ] [ dirname ] [ ] [ VARNAME=VAR_VALUE ] [ ] [ ] [ other s ] }}} The job file describes a sequence of tasks. The descriptor for each task includes: '''application''':: The logical name of the application, or 'worker program'. '''stdin_filename''', '''stdout_filename''', '''stderr_filename''':: The logical names of the files to which stdin, stdout, and stderr are to be connected (if any). '''command_line''':: command-line arguments to be passed to the worker program. You can use the $NTHREADS macro which will be replaced by the number of threads (or processes for MPI applications) that BOINC is allocating for the application. '''weight''':: the contribution of each task to the overall fraction done is proportional to its weight (floating-point, default 1). For example, if your job has tasks A and B, and A uses 100 times more CPU time than B, set A.weight=100 and B.weight=1. '''checkpoint_filename''':: the name of the checkpoint file used by the app, if any. When this is modified, the wrapper assumes that a checkpoint has been completed and notifies the core client. '''fraction_done_filename''':: the name of a file to which the app will periodically write its fraction done (0 to 1). This is used by the wrapper to report overall fraction done. '''exec_dir''':: The directory to start the application (relative to slot, or use $PROJECT_DIR macro) '''multi_process''':: Include this if the application creates multiple processes. '''setenv''':: Environmental variable needed for the applications run-time environment - you can have more than one entry, use the VARNAME=VAR_VALUE form, e.g. LD_LIBRARY_PATH=$PROJECT_DIR:$LD_LIBRARY_PATH. You can also use the $NTHREADS macro if you have an environment variable that needs the number of threads or processes to launch. '''daemon''':: Denotes that this task is a 'daemon' process that should run in the background asynchronously while the other tasks are run sequentially. The wrapper will shut down this daemon when the last task has exited '''append_cmdline_args''':: if set, the wrapper's command-line arguments (specified in the [WorkGeneration#templates input template]) are passed to the worker program, after those in . The job file can specify multiple tasks. This is useful for two purposes: * To handle jobs that involve multiple steps (e.g., pre-processing and post-processing). * To break a long job up into smaller pieces. This provides a form of checkpointing: ''wrapper'' does checkpointing at the task level, so that lost CPU time is limited even if the legacy applications themselves are not restartable. Notes: * One or more of the tasks may be [AppMultiThread multi-threaded] and/or [AppCoprocessor use GPUs]. * Normally the job file is part of the application version (it's the same between workunits). Alternatively, it can be part of the workunit (e.g. if its command line elements differ between workunits). This requires that you use the same worker program logical names for all platforms. * Files opened directly by a worker program must have the tag. This requires version 5.5 or higher of the BOINC core client (you can specify this limit at either the [AppVersion application] or [ProjectOptions#Clientcontrol project] level. * Worker programs must exit with zero status; nonzero values are interpreted as errors by the wrapper. * If you run '''wrapper''' in standalone mode (while debugging), you must provide input files with the proper logical, not physical, names. * The job file may be slightly different for different platforms (i.e. app_versions) due to directory requirements (exec_dir) and environment variables (setenv) required. You will therefore want to make and track different versions for each app_version you are supporting. == Example == Assume you have an executable program for a particular platform (say "worker_windows_intelx6_0.exe" for Win32). The program reads from '''in''' and writes to '''out'''. (You can use the program in '''samples/worker/''' for this purpose). We assume that you have already [MakeProject created a project] with root directory PROJECT/. Now * Download the wrapper for Win32 (see links above) to your server .Assume the filename is '''wrapper_windows_intelx86_25825.exe'''. * [AppVersion Create an application] named 'worker'. * Create the directory hierarchy {{{ apps/ worker/ 1.0/ windows_intelx86/ }}} * Put the files '''wrapper_windows_intelx86_25825.exe''' and '''worker_windows_intelx86_0.exe''' in the bottom directory. * In the same directory, create a file '''worker_job_1.0.xml''' (1.0 is a version number) containing {{{ worker 10 }}} * In the same directory, create a file '''version.xml''' containing {{{ wrapper_windows_intelx86_25825.exe worker_windows_intelx86_0.exe worker worker_job_1.0.xml job.xml }}} * In the 'PROJECT/templates' directory create a workunit template file called 'worker_in': {{{ 0 0 infile 1e12 1e14 }}} and a result template file called 'worker_out' {{{ 5000000 out }}} * Run [UpdateVersions bin/update_versions] to create an app version. * Run [StartTool 'bin/start'] to start the daemons. * Create an input file '''input''', and run a script like {{{ #! /bin/sh cp input `bin/dir_hier_path input` bin/create_work --appname worker --wu_name worker_nodelete input }}} to generate a workunit. == Physical file management == You can use the wrapper together with [PhysicalFileManagement physical file management], where you directly access files in your project directory. For example, you could create a job whose first task unpacks a zip file into the project directory, and whose subsequent tasks access these files. The support for this is: * If a worker program name begins with "$PROJECT_DIR", that substring is replaced with the project directory, and the name is treated as a physical name. * In task command lines, "$PROJECT_DIR" is replaced with the project directory. == Graphics == You can include a [GraphicsApi graphics app] with a wrapper-based application. == !GenWrapper: A more general BOINC wrapper == When the functionality of the BOINC Wrapper is not enough, there is a generic solution which uses POSIX-like shell scripting, instead of the XML config file, for describing jobs: You can have complex control flows (loops, branches, etc), but remember "with great power must also come -- great responsibility!" !GenWrapper homepage is [http://genwrapper.sourceforge.net here], documentation is [http://sourceforge.net/apps/trac/genwrapper/wiki/manual here].