From 0a4f1697deb6e316f6334e552a7177aa896dd736 Mon Sep 17 00:00:00 2001 From: Xin An <34663977+xinan1911@users.noreply.github.com> Date: Wed, 18 Sep 2024 10:25:05 +0200 Subject: [PATCH 01/31] Update picas examples and token commands edit README.md --- README.md | 46 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 329bc14..325034e 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,11 @@ cd picasclient pip install -U . ``` +If you come across error messages related to python, you can execute pip module for a specific python version using the corresponding python: +``` +python3.9 -m pip install -U . +``` + Testing ======= @@ -33,29 +38,62 @@ Examples ## Setting up the examples -The examples directory contains examples to use the picasclient. There are examples for running locally (laptop, cluster login), slurm and the Grid (https://www.egi.eu/), and in principle the jobs can be sent to any machine that can run this client. +The examples directory contains examples to use the picasclient. There are examples for running locally (laptop, cluster login), to a slurm job scheduler and the Grid (https://www.egi.eu/), and in principle the jobs can be sent to any machine that can run this client. -To run the examples, first you need to have a CouchDB instance running that functions as the token broker that stores the tokens which the worker machines can approach to get work execute. To set up this CouchDB instance, see the [SURF documentation](https://doc.grid.surfsara.nl/en/latest/Pages/Practices/picas/picas_overview.html#picas-server-1), these examples assume you have an instance running and access to a DB on this instance. +To run the examples, first you need to have a CouchDB instance running that functions as the token broker that stores the tokens which the worker machines can approach to get work execute. To set up this CouchDB instance, see the [SURF documentation](https://doc.grid.surfsara.nl/en/latest/Pages/Practices/picas/picas_overview.html#picas-server-1), these examples assume you have an instance running and access to a DB on this instance. If you are following a workshop organized by SURF, this has already been arranged for you. Once this server is running, you can run the PiCaS examples: - Local - Slurm - Grid -To approach the DB, you have to fill in the `examples/picasconfig.py` with the information to log in to your CouchDB instance and the database you want use for storing the work tokens. +## Prepare the tokens + + +To approach the DB, you have to fill in the `examples/picasconfig.py` with the information to log in to your CouchDB instance and the database you want use for storing the work tokens. Specifically, the information needed are: +``` +PICAS_HOST_URL="https://picas.surfsara.nl:6984" +PICAS_DATABASE="" +PICAS_USERNAME="" +PICAS_PASSWORD="" +``` +### Create views Once you can approach the server, you have to define "view" logic, so that you can easily view large numbers of tokens and filter on new, running and finished tokens. To create these views, run: ``` python createViews.py ``` -Next you have to send some tokens containing work to the CouchDB instance. You can send two types of work in this example. For very fast running jobs, send the `quickExample.txt` file with: +### Create tokens +This example includes a bash script `(./createTokens)` that generates a sensible parameter file, with each line representing a set of parameters that the fractals program can be called with. Without arguments it creates a fairly sensible set of 24 lines of parameters. You can generate different sets of parameters by calling the program with a combination of `-q`, `-d` and `-m` arguments, but at the moment no documentation exists on these. We recommend not to use them for the moment. +``` +./createTokens +``` +After you ran the `createTokens` script you’ll see output similar to the following: +``` +/tmp/tmp.fZ33Kd8wXK +cat /tmp/tmp.fZ33Kd8wXK +``` + +### Upload tokens to the PiCaS server + +Next you have to send some tokens containing work to the CouchDB instance. You can send two types of work in this example. For very fast running jobs, send the `quickExample.txt` file with: ``` python pushTokens.py quickExample.txt ``` +For longer jobs with a set of 24 lines of parameters. send the file generated in the create tokens step: +``` +python pushTokens.py /tmp/tmp.fZ33Kd8wXK +``` + +### Reset tokens + +### Delete tokens + + Now we are ready to run the examples! ## Running locally From 6baea120ae10ea72e32f97c2c03ad564411ff6fb Mon Sep 17 00:00:00 2001 From: Xin An <34663977+xinan1911@users.noreply.github.com> Date: Wed, 18 Sep 2024 12:01:55 +0200 Subject: [PATCH 02/31] move Grid example to this page --- README.md | 141 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 128 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 325034e..069fb7b 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ Next you have to send some tokens containing work to the CouchDB instance. You c python pushTokens.py quickExample.txt ``` -For longer jobs with a set of 24 lines of parameters. send the file generated in the create tokens step: +For longer jobs example with a set of 24 lines of parameters. send the file generated in the create tokens step: ``` python pushTokens.py /tmp/tmp.fZ33Kd8wXK ``` @@ -94,7 +94,7 @@ python pushTokens.py /tmp/tmp.fZ33Kd8wXK ### Delete tokens -Now we are ready to run the examples! +Now we are ready to run the examples! You can start with running a quick example on different systems. Or you can jump to "Running the long jobs" section for a more complex example. ## Running locally @@ -147,35 +147,131 @@ Now in a slurm job array the work will be performed (you can set the number of a ## Running on Grid -### Fractal example +In this fractal example we will implement the following pilot job workflow: -On the grid, in our screnario, you need to supply the entire environment through the sandbox (a more grid-native CVMFS example is available in the [picas-profile](https://github.com/sara-nl/picas-profile) repository). The binaries and python code need to be in this sandbox. -First we need to create a tar of the picas code, so that it can be sent to the Grid: +* First we define and generate the application tokens with all the necessary parameters. +* Then we define and create a shell script to process one task (*process_task.sh*) that will be sent with the job using the input sandbox. This contains some boiler plate code to e.g. setup the environment, download software or data from the Grid storage, run the application etc. This doesn’t have to be a shell script, however, setting up environment variables is easiest when using a shell script, and this way setup scripts are separated from the application code. +* We also define and create a Python script to handle all the communication with the token pool server, call the process_task,sh script, catch errors and do the reporting. +* Finally we define the :abbr:`JDL (Job Description Language)` on the User Interface machine to specify some general properties of our jobs. This is required to submit a batch of pilot jobs to the Grid that will in turn initiate the Python script as defined in the previous step. + +### Prerequisites + +To be able to run the example you must have: + +* All the three Grid :ref:`prerequisites` (User Interface machine, Grid certificate, VO membership) +* An account on PiCaS server (send your request to ) + + + +### Picas sample example + + +* Log in to the :abbr:`UI (User Interface)` and download the :download:`pilot_picas_fractals.tgz ` example, the couchdb package for Python :download:`couchdb.tgz ` and the fractals source code :download:`fractals.c `. + +* Untar ``pilot_picas_fractals.tgz`` and inspect the content: + +``` +tar -xvf pilot_picas_fractals.tgz +cd pilot_picas_fractals/ +ls -l +-rwxrwxr-x 1 homer homer 1247 Jan 28 15:40 createTokens +-rw-rw-r-- 1 homer homer 1202 Jan 28 15:40 createTokens.py +-rw-rw-r-- 1 homer homer 2827 Jan 28 15:40 createViews.py +-rw-rw-r-- 1 homer homer 462 Jan 28 15:40 fractals.jdl +drwxrwxr-x 2 homer homer 116 Jan 28 15:40 sandbox +``` + +Detailed information regarding the operations performed in each of the scripts below is embedded to the comments inside each of the scripts individually. + +* Also download the current PiCaS version :download:`picas.tar ` and put both PiCaS and the couchdb.tgz file in the ``sandbox`` directory: + +``` +cd sandbox +mv ../../couchdb.tgz ./ +mv ../../picas.tar ./ +``` + +* And finally compile the fractals program (and put it in the sandbox directory) and move one directory up again: +``` +cc ../../fractals.c -o fractals -lm +cd .. +``` + +The sandbox directory now holds everything we need to send to the Grid worker nodes. + +Create the Tokens + +This example includes a bash script (``./createTokens``) that generates a sensible parameter file, with each line representing a set of parameters that the fractals program can be called with. Without arguments it creates a fairly sensible set of 24 lines of parameters. You can generate different sets of parameters by calling the program with a combination of ``-q``, ``-d`` and ``-m`` arguments, but at the moment no documentation exists on these. We recommend not to use them for the moment. + +* After you ran the ``createTokens`` script you'll see output similar to the following: +``` +./createTokens +/tmp/tmp.fZ33Kd8wXK +cat /tmp/tmp.fZ33Kd8wXK +``` +Now we will start using PiCaS. For this we need the downloaded CouchDB and PiCaS packages for Python and set the hostname, database name and our credentials for the CouchDB server: + +* Edit ``sandbox/picasconfig.py`` and set the PiCaS host URL, database name, username and password. + +``` +ln -s sandbox/picasconfig.py +``` + +* Make the CouchDB package locally available: ``` -tar cfv grid-sandbox/picas.tar ../picas/ +tar -xvf sandbox/couchdb.tgz ``` -Secondly, the CouchDB python API needs to be available too, so download and extract it: +* Upload the tokens: + +``` +$python createTokens.py /tmp/tmp.fZ33Kd8wXK +``` +* Check your database in this link: ``` -wget https://files.pythonhosted.org/packages/7c/c8/f94a107eca0c178e5d74c705dad1a5205c0f580840bd1b155cd8a258cb7c/CouchDB-1.2.tar.gz +https://picas.surfsara.nl:6984/_utils/#/database/homerdb/_all_docs (replace homerdb with your Picas database name) ``` -Now you can start the example from a grid login node with (in this case DIRAC is used for job submission): +* Create the Views (pools) - independent to the tokens (should be created only once): ``` -dirac-wms-job-submit grid-example.jdl +python createViews.py ``` +To make use of the dirac tool, first source the dirac env -And the status and output can be retrieved with DIRAC commands, while in the token you see the status of the token and the tokens' attachments contain the log files. Once all tokens have been processed (this can be seen in the CouchDB instance) the grid job will finish. +``` +source /etc/diracosrc +``` + +* Create a proxy: +``` +dirac-proxy-init -b 2048 -g lsgrid_user -M lsgrid --valid 168:00 # replace lsgrid with your VO +``` + +* Submit the pilot jobs: +``` +dirac-wms-job-submit fractals.jdl -f jobIDs +``` + + +It will recursively generate an image based on parameters received from PiCas. At this point, some of your tokens are processed on the Grid worker nodes and some of the tokens are already processed on the :abbr:`UI (User Interface)`. Note that the :abbr:`UI (User Interface)` is not meant for production runs, but only for testing few runs before submitting the pilot jobs to the Grid. + +* Convert the :abbr:`UI (User Interface)` output file to .png format and display the picture: +``` +convert output_token_6 output_token_6.png # replace with your output filename +``` + +For the tokens that are processed on Grid, you can send the output to the :ref:`Grid Storage ` or some other remote location. As we have seen, through PiCaS you have a single interface that can store tokens with work to be done (the CouchDB instance). Then on any machine where you can deploy the PiCaS client, one can perform the tasks hand. ## Running the long jobs -The example above is very fast in running (it only echos to your shell). To get an idea on longer running jobs there is also a "fractal" example. The work in this example takes from 10 seconds up to 30 minutes per token. To add these tokens to your DB, do: +The example above is very fast in running (it only echos to your shell). To get an idea on longer running jobs there is also a "fractal" example. +The work in this example takes from 10 seconds up to 30 minutes per token. To add these tokens to your DB, do: ``` ./createTokens @@ -191,6 +287,7 @@ python pushTokens.py /tmp/tmp.abc123 Now the tokens are available in the database. Next, the binary for the fractal calculation needs to be built: ``` +mkdir bin cc src/fractals.c -o bin/fractals -lm ``` @@ -203,13 +300,31 @@ eval $INPUT with: ``` +cd bin ./fractals -o $OUTPUT $INPUT ``` to ensure the fractal code is called. -Now, you can run your jobs whichever way you want (locally, slurm, grid) and start running using the general instructions as described above! +Now, you can run your jobs whichever way you want (locally, slurm, grid) and start submitting job! + +It will recursively generate an image based on parameters received from PiCas. Once the jobs are run successfully, you can find the output in the bin directory. +Convert the output file to .png format and display the picture: +``` +convert output_token_6 output_token_6.png # replace with your output filename +display output_token_6.png +``` + +## Checking failed jobs + +While your pilot jobs process tasks, you can keep track of their progress through the CouchDB web interface. There are views installed to see: + + * all the tasks that still need to be done (Monitor/todo) + * the tasks that are locked (Monitor/locked) + * tasks that encountered errors (Monitor/error) + * tasks that are finished (Monitor/done) +When all your pilot jobs are finished, ideally, you'd want all tasks to be 'done'. However, often you will find that not all jobs finished successfully and some are still in a 'locked' or 'error' state. If this happens, you should investigate what went wrong with these jobs. Incidentally, this will be due to errors with the middleware, network or storage. In those cases, you can remove the locks and submitting some new pilot jobs to try again. In other cases, there could be errors with your task: maybe you've sent the wrong parameters or forgot to download all necessary input files. Reviewing these failed tasks gives you the possibility to correct them and improve your submission scripts. After that, you could run those tasks again, either by removing their locks or by creating new tokens if needed and then submitting new pilot jobs. Picas overview ============== From d2563cf84a68b8c2fd83cf077a12602b564b588f Mon Sep 17 00:00:00 2001 From: Xin An <34663977+xinan1911@users.noreply.github.com> Date: Mon, 23 Sep 2024 10:33:24 +0200 Subject: [PATCH 03/31] add delete tokens instruction --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 069fb7b..5ee1db3 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,12 @@ python pushTokens.py /tmp/tmp.fZ33Kd8wXK ### Delete tokens +To delete all the Tokens in a certain view, you can use the `deteleTokens.py` under the `examples` directory. For example to delete all the tokens in todo view, run +``` +python /path-to-script/deleteTokens.py Monitor/todo +``` + + Now we are ready to run the examples! You can start with running a quick example on different systems. Or you can jump to "Running the long jobs" section for a more complex example. From e4ce4db83cc01a17627b8c8649e47642beb18895 Mon Sep 17 00:00:00 2001 From: Xin An <34663977+xinan1911@users.noreply.github.com> Date: Mon, 23 Sep 2024 10:34:28 +0200 Subject: [PATCH 04/31] add deleteTokens.py --- examples/deleteTokens.py | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 examples/deleteTokens.py diff --git a/examples/deleteTokens.py b/examples/deleteTokens.py new file mode 100644 index 0000000..ddb5ac8 --- /dev/null +++ b/examples/deleteTokens.py @@ -0,0 +1,43 @@ +''' +Created on 17 March 2016 + +@author: Natalie Danezi +@helpdesk: SURFsara helpdesk + +usage: python deleteTokens.py [viewname] + e.g. python deleteTokens.py Monitor/todo + +description: + Connect to PiCaS server + Delete all the Tokens in the [viewname] View +''' + +import sys + +import couchdb +import picasconfig + + +def deleteDocs(db, viewname): + # v=db.view("Monitor/todo") + v = db.view(viewname) + for x in v: + document = db[x['key']] + db.delete(document) + + +def get_db(): + server = couchdb.Server(picasconfig.PICAS_HOST_URL) + username = picasconfig.PICAS_USERNAME + pwd = picasconfig.PICAS_PASSWORD + server.resource.credentials = (username, pwd) + db = server[picasconfig.PICAS_DATABASE] + return db + + +if __name__ == '__main__': + # Create a connection to the server + db = get_db() + # Delete the Docs in [viewname] + viewname = str(sys.argv[1]) + deleteDocs(db, viewname) From f09c006375be21909b857e2fab2bcb0e22d4053c Mon Sep 17 00:00:00 2001 From: Xin An <34663977+xinan1911@users.noreply.github.com> Date: Tue, 29 Oct 2024 11:30:42 +0100 Subject: [PATCH 05/31] Create token-commands.md --- docs/token-commands.md | 53 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 docs/token-commands.md diff --git a/docs/token-commands.md b/docs/token-commands.md new file mode 100644 index 0000000..634e89a --- /dev/null +++ b/docs/token-commands.md @@ -0,0 +1,53 @@ +PiCaS token commands +============ + +This page introduces the most used commands for preparing and editing tokens. + +### Connect to token pool server on CouchDB + +To approach the DB, you have to fill in the `examples/picasconfig.py` with the information to log in to your CouchDB instance and the database you want use for storing the work tokens. Specifically, the information needed are: +``` +PICAS_HOST_URL="https://picas.surfsara.nl:6984" +PICAS_DATABASE="" +PICAS_USERNAME="" +PICAS_PASSWORD="" +``` +### Create views +Once you can approach the server, you have to define "view" logic, so that you can easily view large numbers of tokens and filter on new, running and finished tokens. To create these views, run: + +``` +python createViews.py +``` + +### Create tokens +This example includes a bash script `(./createTokens)` that generates a sensible parameter file, with each line representing a set of parameters that the fractals program can be called with. Without arguments it creates a fairly sensible set of 24 lines of parameters. You can generate different sets of parameters by calling the program with a combination of `-q`, `-d` and `-m` arguments, but at the moment no documentation exists on these. We recommend not to use them for the moment. +``` +./createTokens +``` +After you ran the `createTokens` script you’ll see output similar to the following: +``` +/tmp/tmp.fZ33Kd8wXK +cat /tmp/tmp.fZ33Kd8wXK +``` + +### Upload tokens to the PiCaS server + + +Next you have to send some tokens containing work to the CouchDB instance. You can send two types of work in this example. For very fast running jobs, send the `quickExample.txt` file with: +``` +python pushTokens.py quickExample.txt +``` + +For longer jobs example with a set of 24 lines of parameters. send the file generated in the create tokens step: +``` +python pushTokens.py /tmp/tmp.fZ33Kd8wXK +``` + +### Reset tokens + +### Delete tokens + +To delete all the Tokens in a certain view, you can use the `deteleTokens.py` under the `examples` directory. For example to delete all the tokens in todo view, run +``` +python /path-to-script/deleteTokens.py Monitor/todo +``` From 6479f04adf14f6460bd30981ff228f737a014080 Mon Sep 17 00:00:00 2001 From: Xin An <34663977+xinan1911@users.noreply.github.com> Date: Tue, 29 Oct 2024 11:57:55 +0100 Subject: [PATCH 06/31] Create quick-example.md --- docs/quick-example.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 docs/quick-example.md diff --git a/docs/quick-example.md b/docs/quick-example.md new file mode 100644 index 0000000..25d4183 --- /dev/null +++ b/docs/quick-example.md @@ -0,0 +1,29 @@ +PiCaS quick example +============ + +To demonstrate how pilot job PiCaS works, this page gives instructions on running a quick example which takes probably a few minutes. The quick example including four main steps: + 1. connect to Picas server + 2. prepare and upload tokens to Picas server + 3. run Picas example pilot job + 4. check the tokens and results + + +## Prerequisite + +Before running the example, please read the README.md in [Picas Client](https://github.com/sara-nl/picasclient/). The prerequisites are: + * you have installed and tested the Picas client + * you have a Picas account and a Picas database + * there is a Picas token pool server running on CouchDB. + +If you are following a workshop organized by SURF, the last two requirements have already been arranged for you. + + +## Connect to Picas server + +## Prepare and upload tokens + +## Run Picas example + +## Check the tokens and results + + From da30a73310f58d6c259be9ab1521ed3fa6e16a88 Mon Sep 17 00:00:00 2001 From: Xin An <34663977+xinan1911@users.noreply.github.com> Date: Tue, 29 Oct 2024 15:00:58 +0100 Subject: [PATCH 07/31] Update quick-example.md --- docs/quick-example.md | 118 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/docs/quick-example.md b/docs/quick-example.md index 25d4183..d7e1acf 100644 --- a/docs/quick-example.md +++ b/docs/quick-example.md @@ -20,10 +20,128 @@ If you are following a workshop organized by SURF, the last two requirements hav ## Connect to Picas server +To connect to the Picas server CouchDB, you need to fill in the `examples/picasconfig.py` with the information to log in to your Picas server and the database you want use for storing the work tokens. Specifically, the information needed are: +``` +PICAS_HOST_URL="https://picas.surfsara.nl:6984" +PICAS_DATABASE="" +PICAS_USERNAME="" +PICAS_PASSWORD="" +``` + +Save and exit. Next don't forget to change the permissions of `examples/picasconfig.py`. Run: +``` +cd examples +chmod 600 picasconfig.py +``` + +For the first time using Picas, you need to define "view" logic and create views. CouchDB views are the basic query mechanism in CouchDB and allow you to extract, transform and combine data from different documents stored in the same database. + +To create these views, run: + +``` +python createViews.py +``` +Once it is finished, you should be able to see the views in the [CouchDB web interface](https://picas.surfsara.nl:6984/_utils/#/database/database-name/). The link needs to be adjusted with your database name + ## Prepare and upload tokens +Next you need to send some tokens containing work to the Picas server. For a quick example with fast running jobs, a `quickExample.txt` file is prepared containing three tokens. Run: +``` +python pushTokens.py quickExample.txt +``` + ## Run Picas example +In principle, the pilot jobs can be sent to any machine that can run Picas client. For this Picas quick example, we provide instructions on running locally (laptop, cluster login), to a slurm job scheduler and the [Grid](https://www.egi.eu/). + +### Running locally + +To run the example locally, run from the `examples` directory: + +``` +python local-example.py +``` + +If all goes well you should see output like: + +``` +----------------------- +Working on token: token_0 +_id token_0 +_rev 4-8b04da64c0a536bb88a3cdebe12e0a87 +type token +lock 1692692693 +done 0 +hostname xxxxxxxxxxxxxxxxxxxxxxx +scrub_count 0 +input echo "bash-echo" +exit_code 0 +----------------------- +``` + +The token in the database will have attachments with the regular and error output of the terminal. There will find the output file `logs_token_0.out`, containing the output of the input command: + +``` +echo "bash-echo" +>>> bash-echo +``` + +Once the script is running, it will start polling the Picas server for work. Once the work is complete, the script will finish. + +Tokens have status, which will go from "todo" to "done" once the work has been completed (or "failed" if the work fails). To do more work, you will have to add new tokens that are not in a "done" state yet, otherwise the example script will just stop after finding no more work to do. + +### Running on a cluster with Slurm + +To start the slurm job which runs the PiCaS client, run the `slurm-example.sh` from the `examples` directory: + +``` +sbatch slurm-example.sh +``` + +Now in a slurm job array the work will be performed (you can set the number of array jobs in the script at `--array`) and each job will start polling the CouchDB instance for work. Once the work is complete, the slurm job will finish. +If you are interested, you can look into scripts `examples/local-example.py` and `examples/process_task.sh` to check what the actual work is. + +### Running on the Grid + +On the grid, in our screnario, you need to supply the entire environment through the sandbox (a more grid-native CVMFS example is available in the [picas-profile](https://github.com/sara-nl/picas-profile) repository). The binaries and python code need to be in this sandbox. +First we need to create a tar of the picas code, so that it can be sent to the Grid: + +``` +tar cfv grid-sandbox/picas.tar ../picas/ +``` + +Secondly, the CouchDB python API needs to be available too, so download and extract it: + +``` +wget https://files.pythonhosted.org/packages/7c/c8/f94a107eca0c178e5d74c705dad1a5205c0f580840bd1b155cd8a258cb7c/CouchDB-1.2.tar.gz +``` + +Now you can start the example from a grid login node with (in this case DIRAC is used for job submission): + +``` +dirac-wms-job-submit grid-example.jdl +``` + +And the status and output can be retrieved with DIRAC commands, while in the token you see the status of the token and the tokens' attachments contain the log files. Once all tokens have been processed (this can be seen in the CouchDB instance) the grid job will finish. + +As we have seen, through PiCaS you have a single interface that can store tokens with work to be done (the CouchDB instance). Then on any machine where you can deploy the PiCaS client, one can perform the tasks hand. + + ## Check the tokens and results +While your pilot jobs process tasks, you can keep track of their progress through the CouchDB web interface. There are views installed to see: + + * all the tasks that still need to be done (Monitor/todo) + * the tasks that are locked (Monitor/locked) + * tasks that encountered errors (Monitor/error) + * tasks that are finished (Monitor/done) + +When all your pilot jobs are finished, ideally you'd want all tasks to be 'done'. However, often you will find that not all jobs finished successfully and some are still in a 'locked' or 'error' state. If this happens, you should investigate what went wrong with these jobs. Incidentally, this might be due to errors with the middleware, network or storage. In those cases, you can remove the locks and submitting some new pilot jobs to try again. + +In other cases, there could be errors with your task: maybe you've sent the wrong parameters or forgot to download all necessary input files. Reviewing these failed tasks gives you the possibility to correct them and improve your submission scripts. After that, you could run those tasks again, either by removing their locks or delete older tokens and creating new tokens. After that, you can submit new pilot jobs. + +To delete all the Tokens in a certain view, you can use the `deteleTokens.py` under the `examples` directory. For example to delete all the tokens in todo view, run +``` +python /path-to-script/deleteTokens.py Monitor/todo +``` From 1920af1c544c759e089cf6b2c561fff540a7850b Mon Sep 17 00:00:00 2001 From: Xin An <34663977+xinan1911@users.noreply.github.com> Date: Thu, 31 Oct 2024 12:27:03 +0100 Subject: [PATCH 08/31] Add picas-views.png --- docs/picas-views.png | Bin 0 -> 178886 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/picas-views.png diff --git a/docs/picas-views.png b/docs/picas-views.png new file mode 100644 index 0000000000000000000000000000000000000000..982f6c430811be28a506226a7cdffdf5d2bea8fe GIT binary patch literal 178886 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℘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�b@Q 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 d_`hnt|MDI4cy504>TY5H0#8>zmvv4FO#n Date: Thu, 31 Oct 2024 12:27:57 +0100 Subject: [PATCH 09/31] Add screenshot of views --- docs/quick-example.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/quick-example.md b/docs/quick-example.md index d7e1acf..7bf8540 100644 --- a/docs/quick-example.md +++ b/docs/quick-example.md @@ -41,7 +41,12 @@ To create these views, run: ``` python createViews.py ``` -Once it is finished, you should be able to see the views in the [CouchDB web interface](https://picas.surfsara.nl:6984/_utils/#/database/database-name/). The link needs to be adjusted with your database name +After a few moments, you should be able to find the generated views in [CouchDB web interface](https://picas.surfsara.nl:6984/_utils/#login). Click on your database and you will see the views on the left under `Monitor/Views`. + +![picas views](./docs/picas-views.png) + + + ## Prepare and upload tokens From de08846d79c4d044dfa665e5c1fa3b0669bd6ee5 Mon Sep 17 00:00:00 2001 From: Xin An <34663977+xinan1911@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:37:56 +0100 Subject: [PATCH 10/31] Create fractal-example.md --- docs/fractal-example.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/fractal-example.md diff --git a/docs/fractal-example.md b/docs/fractal-example.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/docs/fractal-example.md @@ -0,0 +1 @@ + From 3e929f7ac521b385f951bc0b369209b23674995c Mon Sep 17 00:00:00 2001 From: Xin An <34663977+xinan1911@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:53:34 +0100 Subject: [PATCH 11/31] Update fractal-example.md --- docs/fractal-example.md | 139 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/docs/fractal-example.md b/docs/fractal-example.md index 8b13789..67abb7c 100644 --- a/docs/fractal-example.md +++ b/docs/fractal-example.md @@ -1 +1,140 @@ +PiCaS fractal example +============ + +To get an idea on longer running jobs there is also a "fractal" example. The work in this example takes from 10 seconds up to 30 minutes per token. + +The fractal example including four main steps: + 1. connect to Picas server + 2. prepare and upload tokens to Picas server + 3. run Picas example pilot job + 4. check the tokens and results + +## Prerequisite + +Before running the example, please read the README.md in [Picas Client](https://github.com/sara-nl/picasclient/). The prerequisites are: + * you have installed and tested the Picas client + * you have a Picas account and a Picas database + * there is a Picas token pool server running on CouchDB. + +If you are following a workshop organized by SURF, the last two requirements have already been arranged for you. + +## Connect to Picas server + +To connect to the Picas server CouchDB, you need to fill in the `examples/picasconfig.py` with the information to log in to your Picas server and the database you want use for storing the work tokens. Specifically, the information needed are: +``` +PICAS_HOST_URL="https://picas.surfsara.nl:6984" +PICAS_DATABASE="" +PICAS_USERNAME="" +PICAS_PASSWORD="" +``` + +Save and exit. Next don't forget to change the permissions of `examples/picasconfig.py`. Run: +``` +cd examples +chmod 600 picasconfig.py +``` + +For the first time using Picas, you need to define "view" logic and create views. CouchDB views are the basic query mechanism in CouchDB and allow you to extract, transform and combine data from different documents stored in the same database. + +To create these views, run: + +``` +python createViews.py +``` +After a few moments, you should be able to find the generated views in [CouchDB web interface](https://picas.surfsara.nl:6984/_utils/#login). Click on your database and you will see the views on the left under `Monitor/Views`. + +![picas views](./docs/picas-views.png) + + +## Prepare and upload tokens + +Next you need to send some tokens containing work to the Picas server. +To add these tokens to your DB, do: + +``` +./createTokens +>>> /tmp/tmp.abc123 +``` + +And pass the output file to the push tokens code: + +``` +python pushTokens.py /tmp/tmp.abc123 +``` + +## Run Picas example + +Now the tokens are available in the database. First, the binary for the fractal calculation needs to be built: + +``` +cc src/fractals.c -o bin/fractals -lm +``` + +And finally, the `process_task.sh` code needs to call a different command. Replace + +``` +eval $INPUT +``` + +with: + +``` +./fractals -o $OUTPUT $INPUT +``` + +to ensure the fractal code is called. + +In principle, the pilot jobs can be sent to any machine that can run Picas client. For this Picas fractal example, we provide instructions on running locally (laptop, cluster login), to a slurm job scheduler and the [Grid](https://www.egi.eu/). + +### Running locally + +To run the example locally, run from the `examples` directory: + +``` +python local-example.py +``` + +The token in the database will have attachments with the regular and error output of the terminal. + +Once the script is running, it will start polling the Picas server for work. Once the work is complete, the script will finish. + +Tokens have status, which will go from "todo" to "done" once the work has been completed (or "failed" if the work fails). To do more work, you will have to add new tokens that are not in a "done" state yet, otherwise the example script will just stop after finding no more work to do. + +### Running on a cluster with Slurm + +To start the slurm job which runs the PiCaS client, run the `slurm-example.sh` from the `examples` directory: + +``` +sbatch slurm-example.sh +``` + +Now in a slurm job array the work will be performed (you can set the number of array jobs in the script at `--array`) and each job will start polling the CouchDB instance for work. Once the work is complete, the slurm job will finish. +If you are interested, you can look into scripts `examples/local-example.py` and `examples/process_task.sh` to check what the actual work is. + +### Running on Grid + +On the grid, in our screnario, you need to supply the entire environment through the sandbox (a more grid-native CVMFS example is available in the [picas-profile](https://github.com/sara-nl/picas-profile) repository). The binaries and python code need to be in this sandbox. +First we need to create a tar of the picas code, so that it can be sent to the Grid: + +``` +tar cfv grid-sandbox/picas.tar ../picas/ +``` + +Secondly, the CouchDB python API needs to be available too, so download and extract it: + +``` +wget https://files.pythonhosted.org/packages/7c/c8/f94a107eca0c178e5d74c705dad1a5205c0f580840bd1b155cd8a258cb7c/CouchDB-1.2.tar.gz +``` + +Now you can start the example from a grid login node with (in this case DIRAC is used for job submission): + +``` +dirac-wms-job-submit grid-example.jdl +``` + +And the status and output can be retrieved with DIRAC commands, while in the token you see the status of the token and the tokens' attachments contain the log files. Once all tokens have been processed (this can be seen in the CouchDB instance) the grid job will finish. + +As we have seen, through PiCaS you have a single interface that can store tokens with work to be done (the CouchDB instance). Then on any machine where you can deploy the PiCaS client, one can perform the tasks hand. + + From 7ed08e693f4cbb9bec7cad9b54dc9d27266a7746 Mon Sep 17 00:00:00 2001 From: Xin An <34663977+xinan1911@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:55:00 +0100 Subject: [PATCH 12/31] Update deleteTokens.py --- examples/deleteTokens.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/deleteTokens.py b/examples/deleteTokens.py index ddb5ac8..cecb134 100644 --- a/examples/deleteTokens.py +++ b/examples/deleteTokens.py @@ -1,7 +1,5 @@ ''' -Created on 17 March 2016 -@author: Natalie Danezi @helpdesk: SURFsara helpdesk usage: python deleteTokens.py [viewname] From 0bef99eeca699a277ffab498d7a8f7da3e02a5a5 Mon Sep 17 00:00:00 2001 From: Xin An <34663977+xinan1911@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:56:24 +0100 Subject: [PATCH 13/31] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5ee1db3..c541ae1 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Installation To install, first clone the repository and then use pip to install: ``` -git clone git@github.com:sara-nl/picasclient.git +git clone https://github.com/sara-nl/picasclient.git cd picasclient pip install -U . ``` From 371dd20d256d4707d82c41856513f3b0ea12c10e Mon Sep 17 00:00:00 2001 From: Xin An <34663977+xinan1911@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:58:20 +0100 Subject: [PATCH 14/31] Update token-commands.md --- docs/token-commands.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/token-commands.md b/docs/token-commands.md index 634e89a..d853889 100644 --- a/docs/token-commands.md +++ b/docs/token-commands.md @@ -43,7 +43,6 @@ For longer jobs example with a set of 24 lines of parameters. send the file gene python pushTokens.py /tmp/tmp.fZ33Kd8wXK ``` -### Reset tokens ### Delete tokens From cf748aaf563e265ca8e46fd0beafb31eb8aed4f1 Mon Sep 17 00:00:00 2001 From: Xin An <34663977+xinan1911@users.noreply.github.com> Date: Wed, 13 Nov 2024 12:01:57 +0100 Subject: [PATCH 15/31] Update fractal-example.md --- docs/fractal-example.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/fractal-example.md b/docs/fractal-example.md index 67abb7c..e5394d9 100644 --- a/docs/fractal-example.md +++ b/docs/fractal-example.md @@ -114,6 +114,13 @@ If you are interested, you can look into scripts `examples/local-example.py` and ### Running on Grid On the grid, in our screnario, you need to supply the entire environment through the sandbox (a more grid-native CVMFS example is available in the [picas-profile](https://github.com/sara-nl/picas-profile) repository). The binaries and python code need to be in this sandbox. + +The steps will be: +* First we define and generate the application tokens with all the necessary parameters. +* Then we define and create a shell script to process one task (*process_task.sh*) that will be sent with the job using the input sandbox. This contains some boiler plate code to e.g. setup the environment, download software or data from the Grid storage, run the application etc. This doesn’t have to be a shell script, however, setting up environment variables is easiest when using a shell script, and this way setup scripts are separated from the application code. +* We also define and create a Python script to handle all the communication with the token pool server, call the process_task,sh script, catch errors and do the reporting. +* Finally we define the :abbr:`JDL (Job Description Language)` on the User Interface machine to specify some general properties of our jobs. This is required to submit a batch of pilot jobs to the Grid that will in turn initiate the Python script as defined in the previous step. + First we need to create a tar of the picas code, so that it can be sent to the Grid: ``` From 6685fa7d202546e3d2150859688b447454c41f9e Mon Sep 17 00:00:00 2001 From: Xin An <34663977+xinan1911@users.noreply.github.com> Date: Wed, 13 Nov 2024 12:06:42 +0100 Subject: [PATCH 16/31] Update fractal-example.md --- docs/fractal-example.md | 154 +++++++++++++++++----------------------- 1 file changed, 66 insertions(+), 88 deletions(-) diff --git a/docs/fractal-example.md b/docs/fractal-example.md index e5394d9..a29b319 100644 --- a/docs/fractal-example.md +++ b/docs/fractal-example.md @@ -1,147 +1,125 @@ -PiCaS fractal example +PiCaS fractal example in Grid ============ -To get an idea on longer running jobs there is also a "fractal" example. The work in this example takes from 10 seconds up to 30 minutes per token. -The fractal example including four main steps: - 1. connect to Picas server - 2. prepare and upload tokens to Picas server - 3. run Picas example pilot job - 4. check the tokens and results -## Prerequisite +In this fractal example we will implement the following pilot job workflow: -Before running the example, please read the README.md in [Picas Client](https://github.com/sara-nl/picasclient/). The prerequisites are: - * you have installed and tested the Picas client - * you have a Picas account and a Picas database - * there is a Picas token pool server running on CouchDB. +* First we define and generate the application tokens with all the necessary parameters. +* Then we define and create a shell script to process one task (*process_task.sh*) that will be sent with the job using the input sandbox. This contains some boiler plate code to e.g. setup the environment, download software or data from the Grid storage, run the application etc. This doesn’t have to be a shell script, however, setting up environment variables is easiest when using a shell script, and this way setup scripts are separated from the application code. +* We also define and create a Python script to handle all the communication with the token pool server, call the process_task,sh script, catch errors and do the reporting. +* Finally we define the :abbr:`JDL (Job Description Language)` on the User Interface machine to specify some general properties of our jobs. This is required to submit a batch of pilot jobs to the Grid that will in turn initiate the Python script as defined in the previous step. -If you are following a workshop organized by SURF, the last two requirements have already been arranged for you. -## Connect to Picas server +### Prerequisites + +To be able to run the example you must have: + +* All the three Grid :ref:`prerequisites` (User Interface machine, Grid certificate, VO membership) +* An account on PiCaS server (send your request to ) + + + +### Picas sample example -To connect to the Picas server CouchDB, you need to fill in the `examples/picasconfig.py` with the information to log in to your Picas server and the database you want use for storing the work tokens. Specifically, the information needed are: -``` -PICAS_HOST_URL="https://picas.surfsara.nl:6984" -PICAS_DATABASE="" -PICAS_USERNAME="" -PICAS_PASSWORD="" -``` -Save and exit. Next don't forget to change the permissions of `examples/picasconfig.py`. Run: +* Log in to the :abbr:`UI (User Interface)` and download the :download:`pilot_picas_fractals.tgz ` example, the couchdb package for Python :download:`couchdb.tgz ` and the fractals source code :download:`fractals.c `. + +* Untar ``pilot_picas_fractals.tgz`` and inspect the content: + ``` -cd examples -chmod 600 picasconfig.py +tar -xvf pilot_picas_fractals.tgz +cd pilot_picas_fractals/ +ls -l +-rwxrwxr-x 1 homer homer 1247 Jan 28 15:40 createTokens +-rw-rw-r-- 1 homer homer 1202 Jan 28 15:40 createTokens.py +-rw-rw-r-- 1 homer homer 2827 Jan 28 15:40 createViews.py +-rw-rw-r-- 1 homer homer 462 Jan 28 15:40 fractals.jdl +drwxrwxr-x 2 homer homer 116 Jan 28 15:40 sandbox ``` -For the first time using Picas, you need to define "view" logic and create views. CouchDB views are the basic query mechanism in CouchDB and allow you to extract, transform and combine data from different documents stored in the same database. +Detailed information regarding the operations performed in each of the scripts below is embedded to the comments inside each of the scripts individually. -To create these views, run: +* Also download the current PiCaS version :download:`picas.tar ` and put both PiCaS and the couchdb.tgz file in the ``sandbox`` directory: ``` -python createViews.py +cd sandbox +mv ../../couchdb.tgz ./ +mv ../../picas.tar ./ ``` -After a few moments, you should be able to find the generated views in [CouchDB web interface](https://picas.surfsara.nl:6984/_utils/#login). Click on your database and you will see the views on the left under `Monitor/Views`. -![picas views](./docs/picas-views.png) +* And finally compile the fractals program (and put it in the sandbox directory) and move one directory up again: +``` +cc ../../fractals.c -o fractals -lm +cd .. +``` +The sandbox directory now holds everything we need to send to the Grid worker nodes. -## Prepare and upload tokens +Create the Tokens -Next you need to send some tokens containing work to the Picas server. -To add these tokens to your DB, do: +This example includes a bash script (``./createTokens``) that generates a sensible parameter file, with each line representing a set of parameters that the fractals program can be called with. Without arguments it creates a fairly sensible set of 24 lines of parameters. You can generate different sets of parameters by calling the program with a combination of ``-q``, ``-d`` and ``-m`` arguments, but at the moment no documentation exists on these. We recommend not to use them for the moment. +* After you ran the ``createTokens`` script you'll see output similar to the following: ``` ./createTokens ->>> /tmp/tmp.abc123 +/tmp/tmp.fZ33Kd8wXK +cat /tmp/tmp.fZ33Kd8wXK ``` +Now we will start using PiCaS. For this we need the downloaded CouchDB and PiCaS packages for Python and set the hostname, database name and our credentials for the CouchDB server: -And pass the output file to the push tokens code: +* Edit ``sandbox/picasconfig.py`` and set the PiCaS host URL, database name, username and password. ``` -python pushTokens.py /tmp/tmp.abc123 +ln -s sandbox/picasconfig.py ``` -## Run Picas example - -Now the tokens are available in the database. First, the binary for the fractal calculation needs to be built: - +* Make the CouchDB package locally available: ``` -cc src/fractals.c -o bin/fractals -lm +tar -xvf sandbox/couchdb.tgz ``` -And finally, the `process_task.sh` code needs to call a different command. Replace +* Upload the tokens: ``` -eval $INPUT +$python createTokens.py /tmp/tmp.fZ33Kd8wXK ``` -with: - +* Check your database in this link: ``` -./fractals -o $OUTPUT $INPUT +https://picas.surfsara.nl:6984/_utils/#/database/homerdb/_all_docs (replace homerdb with your Picas database name) ``` -to ensure the fractal code is called. - -In principle, the pilot jobs can be sent to any machine that can run Picas client. For this Picas fractal example, we provide instructions on running locally (laptop, cluster login), to a slurm job scheduler and the [Grid](https://www.egi.eu/). - -### Running locally - -To run the example locally, run from the `examples` directory: +* Create the Views (pools) - independent to the tokens (should be created only once): ``` -python local-example.py +python createViews.py ``` - -The token in the database will have attachments with the regular and error output of the terminal. - -Once the script is running, it will start polling the Picas server for work. Once the work is complete, the script will finish. - -Tokens have status, which will go from "todo" to "done" once the work has been completed (or "failed" if the work fails). To do more work, you will have to add new tokens that are not in a "done" state yet, otherwise the example script will just stop after finding no more work to do. - -### Running on a cluster with Slurm - -To start the slurm job which runs the PiCaS client, run the `slurm-example.sh` from the `examples` directory: +To make use of the dirac tool, first source the dirac env ``` -sbatch slurm-example.sh +source /etc/diracosrc ``` -Now in a slurm job array the work will be performed (you can set the number of array jobs in the script at `--array`) and each job will start polling the CouchDB instance for work. Once the work is complete, the slurm job will finish. -If you are interested, you can look into scripts `examples/local-example.py` and `examples/process_task.sh` to check what the actual work is. - -### Running on Grid - -On the grid, in our screnario, you need to supply the entire environment through the sandbox (a more grid-native CVMFS example is available in the [picas-profile](https://github.com/sara-nl/picas-profile) repository). The binaries and python code need to be in this sandbox. - -The steps will be: -* First we define and generate the application tokens with all the necessary parameters. -* Then we define and create a shell script to process one task (*process_task.sh*) that will be sent with the job using the input sandbox. This contains some boiler plate code to e.g. setup the environment, download software or data from the Grid storage, run the application etc. This doesn’t have to be a shell script, however, setting up environment variables is easiest when using a shell script, and this way setup scripts are separated from the application code. -* We also define and create a Python script to handle all the communication with the token pool server, call the process_task,sh script, catch errors and do the reporting. -* Finally we define the :abbr:`JDL (Job Description Language)` on the User Interface machine to specify some general properties of our jobs. This is required to submit a batch of pilot jobs to the Grid that will in turn initiate the Python script as defined in the previous step. - -First we need to create a tar of the picas code, so that it can be sent to the Grid: - +* Create a proxy: ``` -tar cfv grid-sandbox/picas.tar ../picas/ +dirac-proxy-init -b 2048 -g lsgrid_user -M lsgrid --valid 168:00 # replace lsgrid with your VO ``` -Secondly, the CouchDB python API needs to be available too, so download and extract it: - +* Submit the pilot jobs: ``` -wget https://files.pythonhosted.org/packages/7c/c8/f94a107eca0c178e5d74c705dad1a5205c0f580840bd1b155cd8a258cb7c/CouchDB-1.2.tar.gz +dirac-wms-job-submit fractals.jdl -f jobIDs ``` -Now you can start the example from a grid login node with (in this case DIRAC is used for job submission): +It will recursively generate an image based on parameters received from PiCas. At this point, some of your tokens are processed on the Grid worker nodes and some of the tokens are already processed on the :abbr:`UI (User Interface)`. Note that the :abbr:`UI (User Interface)` is not meant for production runs, but only for testing few runs before submitting the pilot jobs to the Grid. + +* Convert the :abbr:`UI (User Interface)` output file to .png format and display the picture: ``` -dirac-wms-job-submit grid-example.jdl +convert output_token_6 output_token_6.png # replace with your output filename ``` -And the status and output can be retrieved with DIRAC commands, while in the token you see the status of the token and the tokens' attachments contain the log files. Once all tokens have been processed (this can be seen in the CouchDB instance) the grid job will finish. +For the tokens that are processed on Grid, you can send the output to the :ref:`Grid Storage ` or some other remote location. As we have seen, through PiCaS you have a single interface that can store tokens with work to be done (the CouchDB instance). Then on any machine where you can deploy the PiCaS client, one can perform the tasks hand. - - From 43a26b49b712a4298642caa0189807cc016a5252 Mon Sep 17 00:00:00 2001 From: Xin An <34663977+xinan1911@users.noreply.github.com> Date: Wed, 13 Nov 2024 12:09:50 +0100 Subject: [PATCH 17/31] Update fractal-example.md --- docs/fractal-example.md | 51 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/docs/fractal-example.md b/docs/fractal-example.md index a29b319..cbe052a 100644 --- a/docs/fractal-example.md +++ b/docs/fractal-example.md @@ -1,8 +1,8 @@ -PiCaS fractal example in Grid +PiCaS fractal example ============ - +## Running in Grid In this fractal example we will implement the following pilot job workflow: * First we define and generate the application tokens with all the necessary parameters. @@ -123,3 +123,50 @@ For the tokens that are processed on Grid, you can send the output to the :ref:` As we have seen, through PiCaS you have a single interface that can store tokens with work to be done (the CouchDB instance). Then on any machine where you can deploy the PiCaS client, one can perform the tasks hand. +## Running locally and in Slurm + +To get an idea on longer running jobs there is also a "fractal" example. +The work in this example takes from 10 seconds up to 30 minutes per token. To add these tokens to your DB, do: + +``` +./createTokens +>>> /tmp/tmp.abc123 +``` + +And pass the output file to the push tokens code: + +``` +python pushTokens.py /tmp/tmp.abc123 +``` + +Now the tokens are available in the database. Next, the binary for the fractal calculation needs to be built: + +``` +mkdir bin +cc src/fractals.c -o bin/fractals -lm +``` + +And finally, the `process_task.sh` code needs to call a different command. Replace + +``` +eval $INPUT +``` + +with: + +``` +cd bin +./fractals -o $OUTPUT $INPUT +``` + +to ensure the fractal code is called. + +Now, you can run your jobs whichever way you want (locally, slurm, grid) and start submitting job! + +## Check the results +It will recursively generate an image based on parameters received from PiCas. Once the jobs are run successfully, you can find the output in the bin directory. +Convert the output file to .png format and display the picture: +``` +convert output_token_6 output_token_6.png # replace with your output filename +display output_token_6.png +``` From 6add1a25715fba0f72c90db61403b9c54be2d214 Mon Sep 17 00:00:00 2001 From: Xin An <34663977+xinan1911@users.noreply.github.com> Date: Wed, 13 Nov 2024 12:18:03 +0100 Subject: [PATCH 18/31] Update README.md --- README.md | 288 ++---------------------------------------------------- 1 file changed, 7 insertions(+), 281 deletions(-) diff --git a/README.md b/README.md index c541ae1..d9828bd 100644 --- a/README.md +++ b/README.md @@ -33,295 +33,21 @@ flake8 picas tests pytest tests ``` -Examples +Token commands ======== -## Setting up the examples - -The examples directory contains examples to use the picasclient. There are examples for running locally (laptop, cluster login), to a slurm job scheduler and the Grid (https://www.egi.eu/), and in principle the jobs can be sent to any machine that can run this client. - -To run the examples, first you need to have a CouchDB instance running that functions as the token broker that stores the tokens which the worker machines can approach to get work execute. To set up this CouchDB instance, see the [SURF documentation](https://doc.grid.surfsara.nl/en/latest/Pages/Practices/picas/picas_overview.html#picas-server-1), these examples assume you have an instance running and access to a DB on this instance. If you are following a workshop organized by SURF, this has already been arranged for you. - -Once this server is running, you can run the PiCaS examples: - - Local - - Slurm - - Grid - - -## Prepare the tokens - - -To approach the DB, you have to fill in the `examples/picasconfig.py` with the information to log in to your CouchDB instance and the database you want use for storing the work tokens. Specifically, the information needed are: -``` -PICAS_HOST_URL="https://picas.surfsara.nl:6984" -PICAS_DATABASE="" -PICAS_USERNAME="" -PICAS_PASSWORD="" -``` -### Create views -Once you can approach the server, you have to define "view" logic, so that you can easily view large numbers of tokens and filter on new, running and finished tokens. To create these views, run: - -``` -python createViews.py -``` - -### Create tokens -This example includes a bash script `(./createTokens)` that generates a sensible parameter file, with each line representing a set of parameters that the fractals program can be called with. Without arguments it creates a fairly sensible set of 24 lines of parameters. You can generate different sets of parameters by calling the program with a combination of `-q`, `-d` and `-m` arguments, but at the moment no documentation exists on these. We recommend not to use them for the moment. -``` -./createTokens -``` -After you ran the `createTokens` script you’ll see output similar to the following: -``` -/tmp/tmp.fZ33Kd8wXK -cat /tmp/tmp.fZ33Kd8wXK -``` - -### Upload tokens to the PiCaS server - - -Next you have to send some tokens containing work to the CouchDB instance. You can send two types of work in this example. For very fast running jobs, send the `quickExample.txt` file with: -``` -python pushTokens.py quickExample.txt -``` - -For longer jobs example with a set of 24 lines of parameters. send the file generated in the create tokens step: -``` -python pushTokens.py /tmp/tmp.fZ33Kd8wXK -``` - -### Reset tokens - -### Delete tokens - -To delete all the Tokens in a certain view, you can use the `deteleTokens.py` under the `examples` directory. For example to delete all the tokens in todo view, run -``` -python /path-to-script/deleteTokens.py Monitor/todo -``` - - - -Now we are ready to run the examples! You can start with running a quick example on different systems. Or you can jump to "Running the long jobs" section for a more complex example. - -## Running locally - -To run the local example do: - -``` -python local-example.py -``` - -If all goes well you should see output like: - -``` ------------------------ -Working on token: token_0 -_id token_0 -_rev 4-8b04da64c0a536bb88a3cdebe12e0a87 -type token -lock 1692692693 -done 0 -hostname ui-01.spider.surfsara.nl -scrub_count 0 -input echo "bash-echo" -exit_code 0 ------------------------ -``` - -The token in de database will have attachments with the regular and error output of the terminal. There will find the output file `logs_token_0.out`, containing the output of the input command: - -``` -echo "bash-echo" ->>> bash-echo -``` - -Once the script is running, it will start polling the CouchDB instance for work. Once the work is complete, the script will finish. - -Tokens have a status, that will go from "todo" to "done" once the work has been completed (or "failed" if the work fails). To do more work, you will have to add new tokens that are not in a "done" state yet, otherwise the example script will just stop after finding no work to do. - -## Running on Slurm - -To run on slurm, first open the `slurm-example.sh` file and make sure your python virtual env or conda/mamba environment is loaded. -Then you have to add tokens to CouchDB using the same setup procedure as mentioned above, with the pushTokens script. - -To start the slurm job that runs the PiCaS client do: - -``` -sbatch slurm-example.sh -``` - -Now in a slurm job array the work will be performed (you can set the number of array jobs in the script at `--array`) and each job will start polling the CouchDB instance for work. Once the work is complete, the jobs will finish. - -## Running on Grid - -In this fractal example we will implement the following pilot job workflow: - -* First we define and generate the application tokens with all the necessary parameters. -* Then we define and create a shell script to process one task (*process_task.sh*) that will be sent with the job using the input sandbox. This contains some boiler plate code to e.g. setup the environment, download software or data from the Grid storage, run the application etc. This doesn’t have to be a shell script, however, setting up environment variables is easiest when using a shell script, and this way setup scripts are separated from the application code. -* We also define and create a Python script to handle all the communication with the token pool server, call the process_task,sh script, catch errors and do the reporting. -* Finally we define the :abbr:`JDL (Job Description Language)` on the User Interface machine to specify some general properties of our jobs. This is required to submit a batch of pilot jobs to the Grid that will in turn initiate the Python script as defined in the previous step. - - -### Prerequisites - -To be able to run the example you must have: - -* All the three Grid :ref:`prerequisites` (User Interface machine, Grid certificate, VO membership) -* An account on PiCaS server (send your request to ) - - - -### Picas sample example - - -* Log in to the :abbr:`UI (User Interface)` and download the :download:`pilot_picas_fractals.tgz ` example, the couchdb package for Python :download:`couchdb.tgz ` and the fractals source code :download:`fractals.c `. - -* Untar ``pilot_picas_fractals.tgz`` and inspect the content: - -``` -tar -xvf pilot_picas_fractals.tgz -cd pilot_picas_fractals/ -ls -l --rwxrwxr-x 1 homer homer 1247 Jan 28 15:40 createTokens --rw-rw-r-- 1 homer homer 1202 Jan 28 15:40 createTokens.py --rw-rw-r-- 1 homer homer 2827 Jan 28 15:40 createViews.py --rw-rw-r-- 1 homer homer 462 Jan 28 15:40 fractals.jdl -drwxrwxr-x 2 homer homer 116 Jan 28 15:40 sandbox -``` - -Detailed information regarding the operations performed in each of the scripts below is embedded to the comments inside each of the scripts individually. +For the most used commands for preparing and editing tokens, check [Picas token commands](/docs/token-commands.md). -* Also download the current PiCaS version :download:`picas.tar ` and put both PiCaS and the couchdb.tgz file in the ``sandbox`` directory: -``` -cd sandbox -mv ../../couchdb.tgz ./ -mv ../../picas.tar ./ -``` - -* And finally compile the fractals program (and put it in the sandbox directory) and move one directory up again: -``` -cc ../../fractals.c -o fractals -lm -cd .. -``` - -The sandbox directory now holds everything we need to send to the Grid worker nodes. - -Create the Tokens - -This example includes a bash script (``./createTokens``) that generates a sensible parameter file, with each line representing a set of parameters that the fractals program can be called with. Without arguments it creates a fairly sensible set of 24 lines of parameters. You can generate different sets of parameters by calling the program with a combination of ``-q``, ``-d`` and ``-m`` arguments, but at the moment no documentation exists on these. We recommend not to use them for the moment. - -* After you ran the ``createTokens`` script you'll see output similar to the following: -``` -./createTokens -/tmp/tmp.fZ33Kd8wXK -cat /tmp/tmp.fZ33Kd8wXK -``` -Now we will start using PiCaS. For this we need the downloaded CouchDB and PiCaS packages for Python and set the hostname, database name and our credentials for the CouchDB server: - -* Edit ``sandbox/picasconfig.py`` and set the PiCaS host URL, database name, username and password. - -``` -ln -s sandbox/picasconfig.py -``` - -* Make the CouchDB package locally available: -``` -tar -xvf sandbox/couchdb.tgz -``` - -* Upload the tokens: - -``` -$python createTokens.py /tmp/tmp.fZ33Kd8wXK -``` - -* Check your database in this link: -``` -https://picas.surfsara.nl:6984/_utils/#/database/homerdb/_all_docs (replace homerdb with your Picas database name) -``` - -* Create the Views (pools) - independent to the tokens (should be created only once): - -``` -python createViews.py -``` -To make use of the dirac tool, first source the dirac env - -``` -source /etc/diracosrc -``` - -* Create a proxy: -``` -dirac-proxy-init -b 2048 -g lsgrid_user -M lsgrid --valid 168:00 # replace lsgrid with your VO -``` - -* Submit the pilot jobs: -``` -dirac-wms-job-submit fractals.jdl -f jobIDs -``` - - -It will recursively generate an image based on parameters received from PiCas. At this point, some of your tokens are processed on the Grid worker nodes and some of the tokens are already processed on the :abbr:`UI (User Interface)`. Note that the :abbr:`UI (User Interface)` is not meant for production runs, but only for testing few runs before submitting the pilot jobs to the Grid. - -* Convert the :abbr:`UI (User Interface)` output file to .png format and display the picture: -``` -convert output_token_6 output_token_6.png # replace with your output filename -``` - -For the tokens that are processed on Grid, you can send the output to the :ref:`Grid Storage ` or some other remote location. - -As we have seen, through PiCaS you have a single interface that can store tokens with work to be done (the CouchDB instance). Then on any machine where you can deploy the PiCaS client, one can perform the tasks hand. - - -## Running the long jobs - -The example above is very fast in running (it only echos to your shell). To get an idea on longer running jobs there is also a "fractal" example. -The work in this example takes from 10 seconds up to 30 minutes per token. To add these tokens to your DB, do: - -``` -./createTokens ->>> /tmp/tmp.abc123 -``` - -And pass the output file to the push tokens code: - -``` -python pushTokens.py /tmp/tmp.abc123 -``` - -Now the tokens are available in the database. Next, the binary for the fractal calculation needs to be built: - -``` -mkdir bin -cc src/fractals.c -o bin/fractals -lm -``` - -And finally, the `process_task.sh` code needs to call a different command. Replace - -``` -eval $INPUT -``` - -with: - -``` -cd bin -./fractals -o $OUTPUT $INPUT -``` +Examples +======== -to ensure the fractal code is called. +There is a [quick example](/docs/quick-example.md) which lasts for a few minutues. Additionally, a [fractal example](/docs/fractal-example.md) is available for running long jobs. -Now, you can run your jobs whichever way you want (locally, slurm, grid) and start submitting job! -It will recursively generate an image based on parameters received from PiCas. Once the jobs are run successfully, you can find the output in the bin directory. -Convert the output file to .png format and display the picture: -``` -convert output_token_6 output_token_6.png # replace with your output filename -display output_token_6.png -``` -## Checking failed jobs +Check job status +======== While your pilot jobs process tasks, you can keep track of their progress through the CouchDB web interface. There are views installed to see: From 6097047c1938a1f5f23ec1f172e271d8beeee628 Mon Sep 17 00:00:00 2001 From: Haili Hu Date: Tue, 3 Dec 2024 22:18:05 +0100 Subject: [PATCH 19/31] Updated README to contain examples --- README.md | 235 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 223 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index d78861e..7823af9 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ picasclient ![CICD](https://github.com/sara-nl/picasclient/actions/workflows/python-app.yml/badge.svg) [![License - MIT](https://img.shields.io/github/license/sara-nl/picasclient)](https://github.com/sara-nl/picasclient/blob/main/LICENSE) -Python client using CouchDB as a token pool server. +Python client using [CouchDB](https://docs.couchdb.org/en/stable/index.html) as a token pool server. Installation ============ @@ -25,12 +25,6 @@ pip install -U . pip install flake8 pytest ``` - -First, install the test dependencies with -``` -pip install ".[test]" -``` -======= To test, run ``` flake8 picas tests @@ -46,18 +40,235 @@ pip install picas You can then write your custom Python program to use `picas` based on the examples below. -Token commands +Examples ======== +The examples directory contains examples to use the picasclient. There are examples for running locally, [Spider](https://doc.spider.surfsara.nl/en/latest/Pages/about.html) (SLURM cluster) and the [Grid](https://doc.grid.surfsara.nl/en/latest/), and in principle the jobs can be sent to any machine that can run this client. -For the most used commands for preparing and editing tokens, check [Picas token commands](/docs/token-commands.md). +Prerequisites +------------- + +
+Connect to the PiCaS server +
+To connect to the PiCaS server, fill `examples/picasconfig.py` with the information needed to log in to your PiCaS account and the database you want use for storing the work tokens. Specifically, the information needed are: + +``` +PICAS_HOST_URL="https://picas.surfsara.nl:6984" +PICAS_DATABASE="" +PICAS_USERNAME="" +PICAS_PASSWORD="" +``` +
-Examples -======== +
+Create DB Views +
+When you you use the DB for the first time, you need to define "view" logic and create views. CouchDB Views are the primary tool used for querying and reporting on CouchDB documents. You can, for example, create views to filter on new, running, finished, and failed job tokens. Some pre-defined views can be created with: + +``` +python createViews.py +``` +This will create the following views: + * Monitor/todo: all the tasks that still need to be done + * Monitor/locked: the tasks that are currently running + * Monitor/error: tasks that encountered errors + * Monitor/done: tasks that are finished + * Monitor/overview_total: all tasks and their states + +After a few moments, you should be able to find the generated views in the CouchDB web interface . Click on your database and you will see the views on the left under `Monitor/Views`: + +![picas views](docs/picas-views.png) +
+ + +Quick example +------------- +
+Create tokens +
+Now you can send some tokens containing work to the Picas server. For fast running jobs, a quickExample.txt file is prepared containing three tokens. Run: + +``` +python pushTokens.py quickExample.txt +``` +Check the DB if you can find the tokens in the View Monitor/todo. +
+ +
+Running locally +
+To run the example locally (e.g. on your laptop), run from the examples directory: + +``` +python local-example.py +``` -There is a [quick example](/docs/quick-example.md) which lasts for a few minutues. Additionally, a [fractal example](/docs/fractal-example.md) is available for running long jobs. +If all goes well you should see output like: +``` +----------------------- +Working on token: token_0 +_id token_0 +_rev 4-8b04da64c0a536bb88a3cdebe12e0a87 +type token +lock 1692692693 +done 0 +hostname xxxxxxxxxxxx +scrub_count 0 +input echo "this is token A" +exit_code 0 +----------------------- +``` + +The token in the database will have attachments with the regular and error output of the terminal. There you will find the output file `logs_token_0.out`, containing the output of the input command: + +``` +Tue 31 Dec 2024 00:00:00 CET +xxxxxxxxxxxx +echo 'this is token A' +token_0 +output_token_0 +this is token A +Tue 31 Dec 2024 00:00:00 CET +``` + + +Once the script is running, it will start polling the Picas server for work. Once the work is complete, the script will finish. + +Tokens have status, which will go from "todo" to "done" once the work has been completed (or "failed" if the work fails). To do more work, you will have to add new tokens that are not in a "done" state yet, otherwise the example script will just stop after finding no more work to do. +
+ +
+Running on a cluster with SLURM +
+To start the SLURM job which runs the PiCaS client, run the `slurm-example.sh` from the `examples` directory: + +``` +sbatch slurm-example.sh +``` + +Now in a SLURM job array the work will be performed (you can set the number of array jobs in the script at `--array`) and each job will start polling the CouchDB instance for work. Once the work is complete, the SLURM job will finish. +If you are interested, you can look into scripts `examples/local-example.py` and `examples/process_task.sh` to check what the actual work is. +
+ +
+Running on the Grid with DIRAC +
+ +On the grid, in our screnario, you need to supply the entire environment through the sandbox (a more grid-native CVMFS example is available in the [picas-profile](https://github.com/sara-nl/picas-profile) repository). The binaries and python code need to be in this sandbox. +First we need to create a tar of the picas code, so that it can be sent to the Grid: + +``` +tar cfv grid-sandbox/picas.tar ../picas/ +``` + +Secondly, the CouchDB python API needs to be available too, so download and extract it: + +``` +wget https://files.pythonhosted.org/packages/7c/c8/f94a107eca0c178e5d74c705dad1a5205c0f580840bd1b155cd8a258cb7c/CouchDB-1.2.tar.gz +``` +Now you can start the example from a grid login node with (in this case DIRAC is used for job submission): + +``` +dirac-wms-job-submit grid-example.jdl +``` + +And the status and output can be retrieved with DIRAC commands, while in the token you see the status of the token and the tokens' attachments contain the log files. Once all tokens have been processed (this can be seen in the CouchDB instance) the grid job will finish. + +As we have seen, through PiCaS you have a single interface that can store tokens with work to be done (the CouchDB instance). Then on any machine where you can deploy the PiCaS client, one can perform the tasks hand. +
+ +
+Check results +
+ +While your pilot jobs process tasks, you can keep track of their progress through the CouchDB web interface and the views we created earlier. + +When all your pilot jobs are finished, ideally you'd want all tasks to be 'done'. However, often you will find that not all jobs finished successfully and some are still in a 'locked' or 'error' state. If this happens, you should investigate what went wrong with these jobs. Incidentally, this might be due to errors with the middleware, network or storage. In those cases, you can remove the locks and submitting some new pilot jobs to try again. + +In other cases, there could be errors with your task: maybe you've sent the wrong parameters or forgot to download all necessary input files. Reviewing these failed tasks gives you the possibility to correct them and improve your submission scripts. After that, you could run those tasks again, either by removing their locks or delete older tokens and creating new tokens. After that, you can submit new pilot jobs. + +To delete all the Tokens in a certain view, you can use the `deteleTokens.py` under the `examples` directory. For example to delete all the tokens in todo view, run + +``` +python /path-to-script/deleteTokens.py Monitor/todo +``` + +
+ +Long example: fractals +---------------------- + +
+Create tokens +
+ +The example above is very fast in running (it only echos to your shell). To get an idea on longer running jobs there is also a "fractal" example. The work in this example takes from 10 seconds up to 30 minutes per token. To add these tokens to your DB, do: + +``` +./createTokens +>>> /tmp/tmp.abc123 +``` + +And pass the output file to the push tokens code: + +``` +python pushTokens.py /tmp/tmp.abc123 +``` +Now the tokens are available in the database. +
+ + +
+Prepare code +
+Next, the binary for the fractal calculation needs to be built: + +``` +cc src/fractals.c -o bin/fractals -lm +``` + +And finally, the `process_task.sh` code needs to call a different command. Replace + +``` +bash -c "$INPUT" +``` +with: + +``` +bin/fractals -o $OUTPUT $INPUT +``` +to ensure the fractal code is called. +
+ +
+Run jobs locally, SLURM cluster or Grid +
+Now, you can run your jobs whichever way you want (locally, SLURM cluster or the Grid, using the general instructions as described above for the short example! +
+ +
+Check results +
+The fractals code will recursively generate an image based on parameters received from PiCas. If the jobs are run locally or on Spider, you can find the output in your work directory. For jobs that are processed on the Grid, you can send the output to the Grid Storage or some other remote location. To check the results, convert the output file to .png format and display the picture: + +``` +convert output_token_6 output_token_6.png # replace with your output filename +display output_token_6.png +``` +
+ + +Token commands +============== + +For the most used commands for preparing and editing tokens, check [Picas token commands](/docs/token-commands.md). Check job status ======== From f0d72e47bc3216cdf5c3f619e749d67926f48c4a Mon Sep 17 00:00:00 2001 From: Haili Hu Date: Wed, 4 Dec 2024 11:17:19 +0100 Subject: [PATCH 20/31] Clean up docs --- README.md | 67 ++++++--------- docs/fractal-example.md | 172 -------------------------------------- docs/quick-example.md | 152 --------------------------------- docs/token-commands.md | 52 ------------ examples/process_task.sh | 3 + examples/quickExample.txt | 6 +- 6 files changed, 32 insertions(+), 420 deletions(-) delete mode 100644 docs/fractal-example.md delete mode 100644 docs/quick-example.md delete mode 100644 docs/token-commands.md diff --git a/README.md b/README.md index 7823af9..de30666 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ picasclient Python client using [CouchDB](https://docs.couchdb.org/en/stable/index.html) as a token pool server. + Installation ============ @@ -31,6 +32,7 @@ flake8 picas tests pytest tests ``` + Installing package ------------------ The latest release of `picas` can be installed as a package from PyPI with: @@ -42,20 +44,20 @@ You can then write your custom Python program to use `picas` based on the exampl Examples ======== -The examples directory contains examples to use the picasclient. There are examples for running locally, [Spider](https://doc.spider.surfsara.nl/en/latest/Pages/about.html) (SLURM cluster) and the [Grid](https://doc.grid.surfsara.nl/en/latest/), and in principle the jobs can be sent to any machine that can run this client. +The `examples` directory contains two examples how to use the PiCaS client: a short example and a long example. These also include scripts for running locally, on [Spider](https://doc.spider.surfsara.nl/en/latest/Pages/about.html) (SLURM cluster) and the [Grid](https://doc.grid.surfsara.nl/en/latest/). The examples will show how PiCaS provides a single interface that can store tokens (on the CouchDB instance) with work to be done. Then jobs can be sent to any machine where the PiCaS client can be deployed. Prerequisites -------------
Get a PiCaS account
-To run the examples, you need a PiCaS account and access to a database (DB) on the PiCaS CouchDB instance. If you are following a workshop organized by SURF, this has already been arranged for you. If you are have a Grid or Spider project at SURF, you can request access through the Service Desk +To run the examples, you need a PiCaS account and access to a database (DB) on the PiCaS CouchDB instance. If you are following a workshop organized by SURF, this has already been arranged for you. If you have a Grid or Spider project at SURF, you can request access through the Service Desk
Connect to the PiCaS server
-To connect to the PiCaS server, fill `examples/picasconfig.py` with the information needed to log in to your PiCaS account and the database you want use for storing the work tokens. Specifically, the information needed are: +To connect to the PiCaS server, fill `examples/picasconfig.py` with the information needed to log in to your PiCaS account and the database you want to use for storing the work tokens. Specifically, the information needed are: ``` PICAS_HOST_URL="https://picas.surfsara.nl:6984" @@ -68,19 +70,20 @@ PICAS_PASSWORD=""
Create DB Views
-When you you use the DB for the first time, you need to define "view" logic and create views. CouchDB Views are the primary tool used for querying and reporting on CouchDB documents. You can, for example, create views to filter on new, running, finished, and failed job tokens. Some pre-defined views can be created with: +When you you use the DB for the first time, you need to define "view" logic and create views. CouchDB Views are the primary tool used for querying and reporting on CouchDB documents. For example, you can create views to filter on new, running, finished, and failed job tokens. Some pre-defined views can be created with: ``` +cd examples python createViews.py ``` This will create the following views: - * Monitor/todo: all the tasks that still need to be done - * Monitor/locked: the tasks that are currently running + * Monitor/todo: tasks that still need to be done + * Monitor/locked: tasks that are currently running * Monitor/error: tasks that encountered errors * Monitor/done: tasks that are finished * Monitor/overview_total: all tasks and their states -After a few moments, you should be able to find the generated views in the CouchDB web interface . Click on your database and you will see the views on the left under `Monitor/Views`: +After a few moments, you should be able to find the generated views in the CouchDB web interface. Select your database and you will see the views on the left under `Monitor/Views`: ![picas views](docs/picas-views.png)
@@ -88,21 +91,23 @@ After a few moments, you should be able to find the generated views in the Create tokens
-Now you can send some tokens containing work to the Picas server. For fast running jobs, a quickExample.txt file is prepared containing three tokens. Run: +The file quickExample.txt contains three lines with commands to be executed. You can generate three job tokens in the PiCaS DB by running: ``` python pushTokens.py quickExample.txt ``` + Check the DB if you can find the tokens in the View Monitor/todo.
Running locally
-To run the example locally (e.g. on your laptop), run from the examples directory: +To run the example locally (e.g. on your laptop) with: ``` python local-example.py @@ -125,7 +130,7 @@ exit_code 0 ----------------------- ``` -The token in the database will have attachments with the regular and error output of the terminal. There you will find the output file `logs_token_0.out`, containing the output of the input command: +The token in the database will have attachments with the standard and error output of the terminal. There you will find the output file `logs_token_0.out`, containing the output of the input command: ``` Tue 31 Dec 2024 00:00:00 CET @@ -137,10 +142,9 @@ this is token A Tue 31 Dec 2024 00:00:00 CET ``` - Once the script is running, it will start polling the Picas server for work. Once the work is complete, the script will finish. -Tokens have status, which will go from "todo" to "done" once the work has been completed (or "failed" if the work fails). To do more work, you will have to add new tokens that are not in a "done" state yet, otherwise the example script will just stop after finding no more work to do. +Tokens have a status, which will go from "todo" to "done" once the work has been completed (or "failed" if the work fails). To do more work, you will have to add new tokens that in the "todo" state yet, otherwise the example script will just stop after finding no more work to do. If you are interested, you can look into the scripts `examples/local-example.py` and `examples/process_task.sh` to check what the actual work is.
@@ -153,7 +157,6 @@ sbatch slurm-example.sh ``` Now in a SLURM job array the work will be performed (you can set the number of array jobs in the script at `--array`) and each job will start polling the CouchDB instance for work. Once the work is complete, the SLURM job will finish. -If you are interested, you can look into scripts `examples/local-example.py` and `examples/process_task.sh` to check what the actual work is.
@@ -179,9 +182,8 @@ Now you can start the example from a grid login node with (in this case DIRAC is dirac-wms-job-submit grid-example.jdl ``` -And the status and output can be retrieved with DIRAC commands, while in the token you see the status of the token and the tokens' attachments contain the log files. Once all tokens have been processed (this can be seen in the CouchDB instance) the grid job will finish. +And the status and output can be retrieved with DIRAC commands, while in the token you see the status of the token and the tokens' attachments contain the log files. Once all tokens have been processed (check the DB Views) the grid job will finish. -As we have seen, through PiCaS you have a single interface that can store tokens with work to be done (the CouchDB instance). Then on any machine where you can deploy the PiCaS client, one can perform the tasks hand.
@@ -194,29 +196,29 @@ When all your pilot jobs are finished, ideally you'd want all tasks to be 'done' In other cases, there could be errors with your task: maybe you've sent the wrong parameters or forgot to download all necessary input files. Reviewing these failed tasks gives you the possibility to correct them and improve your submission scripts. After that, you could run those tasks again, either by removing their locks or delete older tokens and creating new tokens. After that, you can submit new pilot jobs. -To delete all the Tokens in a certain view, you can use the `deteleTokens.py` under the `examples` directory. For example to delete all the tokens in todo view, run +To delete all the Tokens in a certain view, you can use the script `deteleTokens.py`. For example to delete all the tokens in `error` view, run: ``` -python /path-to-script/deleteTokens.py Monitor/todo +python deleteTokens.py Monitor/error ```
+ Long example: fractals ---------------------- +To get an idea on more realistic, longer running jobs there is also a "fractals" example. The fractals code will recursively generate an image based on parameters received from PiCas. The work can take from 10 seconds up to 30 minutes per token.
Create tokens
- -The example above is very fast in running (it only echos to your shell). To get an idea on longer running jobs there is also a "fractal" example. The work in this example takes from 10 seconds up to 30 minutes per token. To add these tokens to your DB, do: +To add the fractals job tokens to your DB, run: ``` ./createTokens >>> /tmp/tmp.abc123 ``` - -And pass the output file to the push tokens code: +This will generate an outputfile, in this case called `/tmp/tmp.abc123`. Pass the outputfile to the `pushTokens.py` code: ``` python pushTokens.py /tmp/tmp.abc123 @@ -224,7 +226,6 @@ python pushTokens.py /tmp/tmp.abc123 Now the tokens are available in the database.
-
Prepare code
@@ -244,19 +245,19 @@ with: ``` bin/fractals -o $OUTPUT $INPUT ``` -to ensure the fractal code is called. +to ensure that the fractals code is called.
Run jobs locally, SLURM cluster or Grid
-Now, you can run your jobs whichever way you want (locally, SLURM cluster or the Grid, using the general instructions as described above for the short example! +Now, you can run your jobs whichever way you want (locally, SLURM cluster or the Grid), using the general instructions as described above for the quick example!
Check results
-The fractals code will recursively generate an image based on parameters received from PiCas. If the jobs are run locally or on Spider, you can find the output in your work directory. For jobs that are processed on the Grid, you can send the output to the Grid Storage or some other remote location. To check the results, convert the output file to .png format and display the picture: +The fractals code will generate an outputfile named `output_token_X`. If the jobs are run locally or on Spider, you can find the outputfile in your work directory. For jobs that are processed on the Grid, you can transfer the outputfile to a remote storage location at the end of your job script `process_task.sh`. To check the results, convert the output file to .png format and display the picture: ``` convert output_token_6 output_token_6.png # replace with your output filename @@ -265,22 +266,6 @@ display output_token_6.png
-Token commands -============== - -For the most used commands for preparing and editing tokens, check [Picas token commands](/docs/token-commands.md). - -Check job status -======== - -While your pilot jobs process tasks, you can keep track of their progress through the CouchDB web interface. There are views installed to see: - - * all the tasks that still need to be done (Monitor/todo) - * the tasks that are locked (Monitor/locked) - * tasks that encountered errors (Monitor/error) - * tasks that are finished (Monitor/done) - -When all your pilot jobs are finished, ideally, you'd want all tasks to be 'done'. However, often you will find that not all jobs finished successfully and some are still in a 'locked' or 'error' state. If this happens, you should investigate what went wrong with these jobs. Incidentally, this will be due to errors with the middleware, network or storage. In those cases, you can remove the locks and submitting some new pilot jobs to try again. In other cases, there could be errors with your task: maybe you've sent the wrong parameters or forgot to download all necessary input files. Reviewing these failed tasks gives you the possibility to correct them and improve your submission scripts. After that, you could run those tasks again, either by removing their locks or by creating new tokens if needed and then submitting new pilot jobs. Picas overview ============== diff --git a/docs/fractal-example.md b/docs/fractal-example.md deleted file mode 100644 index cbe052a..0000000 --- a/docs/fractal-example.md +++ /dev/null @@ -1,172 +0,0 @@ -PiCaS fractal example -============ - - -## Running in Grid -In this fractal example we will implement the following pilot job workflow: - -* First we define and generate the application tokens with all the necessary parameters. -* Then we define and create a shell script to process one task (*process_task.sh*) that will be sent with the job using the input sandbox. This contains some boiler plate code to e.g. setup the environment, download software or data from the Grid storage, run the application etc. This doesn’t have to be a shell script, however, setting up environment variables is easiest when using a shell script, and this way setup scripts are separated from the application code. -* We also define and create a Python script to handle all the communication with the token pool server, call the process_task,sh script, catch errors and do the reporting. -* Finally we define the :abbr:`JDL (Job Description Language)` on the User Interface machine to specify some general properties of our jobs. This is required to submit a batch of pilot jobs to the Grid that will in turn initiate the Python script as defined in the previous step. - - -### Prerequisites - -To be able to run the example you must have: - -* All the three Grid :ref:`prerequisites` (User Interface machine, Grid certificate, VO membership) -* An account on PiCaS server (send your request to ) - - - -### Picas sample example - - -* Log in to the :abbr:`UI (User Interface)` and download the :download:`pilot_picas_fractals.tgz ` example, the couchdb package for Python :download:`couchdb.tgz ` and the fractals source code :download:`fractals.c `. - -* Untar ``pilot_picas_fractals.tgz`` and inspect the content: - -``` -tar -xvf pilot_picas_fractals.tgz -cd pilot_picas_fractals/ -ls -l --rwxrwxr-x 1 homer homer 1247 Jan 28 15:40 createTokens --rw-rw-r-- 1 homer homer 1202 Jan 28 15:40 createTokens.py --rw-rw-r-- 1 homer homer 2827 Jan 28 15:40 createViews.py --rw-rw-r-- 1 homer homer 462 Jan 28 15:40 fractals.jdl -drwxrwxr-x 2 homer homer 116 Jan 28 15:40 sandbox -``` - -Detailed information regarding the operations performed in each of the scripts below is embedded to the comments inside each of the scripts individually. - -* Also download the current PiCaS version :download:`picas.tar ` and put both PiCaS and the couchdb.tgz file in the ``sandbox`` directory: - -``` -cd sandbox -mv ../../couchdb.tgz ./ -mv ../../picas.tar ./ -``` - -* And finally compile the fractals program (and put it in the sandbox directory) and move one directory up again: -``` -cc ../../fractals.c -o fractals -lm -cd .. -``` - -The sandbox directory now holds everything we need to send to the Grid worker nodes. - -Create the Tokens - -This example includes a bash script (``./createTokens``) that generates a sensible parameter file, with each line representing a set of parameters that the fractals program can be called with. Without arguments it creates a fairly sensible set of 24 lines of parameters. You can generate different sets of parameters by calling the program with a combination of ``-q``, ``-d`` and ``-m`` arguments, but at the moment no documentation exists on these. We recommend not to use them for the moment. - -* After you ran the ``createTokens`` script you'll see output similar to the following: -``` -./createTokens -/tmp/tmp.fZ33Kd8wXK -cat /tmp/tmp.fZ33Kd8wXK -``` -Now we will start using PiCaS. For this we need the downloaded CouchDB and PiCaS packages for Python and set the hostname, database name and our credentials for the CouchDB server: - -* Edit ``sandbox/picasconfig.py`` and set the PiCaS host URL, database name, username and password. - -``` -ln -s sandbox/picasconfig.py -``` - -* Make the CouchDB package locally available: -``` -tar -xvf sandbox/couchdb.tgz -``` - -* Upload the tokens: - -``` -$python createTokens.py /tmp/tmp.fZ33Kd8wXK -``` - -* Check your database in this link: -``` -https://picas.surfsara.nl:6984/_utils/#/database/homerdb/_all_docs (replace homerdb with your Picas database name) -``` - -* Create the Views (pools) - independent to the tokens (should be created only once): - -``` -python createViews.py -``` -To make use of the dirac tool, first source the dirac env - -``` -source /etc/diracosrc -``` - -* Create a proxy: -``` -dirac-proxy-init -b 2048 -g lsgrid_user -M lsgrid --valid 168:00 # replace lsgrid with your VO -``` - -* Submit the pilot jobs: -``` -dirac-wms-job-submit fractals.jdl -f jobIDs -``` - - -It will recursively generate an image based on parameters received from PiCas. At this point, some of your tokens are processed on the Grid worker nodes and some of the tokens are already processed on the :abbr:`UI (User Interface)`. Note that the :abbr:`UI (User Interface)` is not meant for production runs, but only for testing few runs before submitting the pilot jobs to the Grid. - -* Convert the :abbr:`UI (User Interface)` output file to .png format and display the picture: -``` -convert output_token_6 output_token_6.png # replace with your output filename -``` - -For the tokens that are processed on Grid, you can send the output to the :ref:`Grid Storage ` or some other remote location. - -As we have seen, through PiCaS you have a single interface that can store tokens with work to be done (the CouchDB instance). Then on any machine where you can deploy the PiCaS client, one can perform the tasks hand. - -## Running locally and in Slurm - -To get an idea on longer running jobs there is also a "fractal" example. -The work in this example takes from 10 seconds up to 30 minutes per token. To add these tokens to your DB, do: - -``` -./createTokens ->>> /tmp/tmp.abc123 -``` - -And pass the output file to the push tokens code: - -``` -python pushTokens.py /tmp/tmp.abc123 -``` - -Now the tokens are available in the database. Next, the binary for the fractal calculation needs to be built: - -``` -mkdir bin -cc src/fractals.c -o bin/fractals -lm -``` - -And finally, the `process_task.sh` code needs to call a different command. Replace - -``` -eval $INPUT -``` - -with: - -``` -cd bin -./fractals -o $OUTPUT $INPUT -``` - -to ensure the fractal code is called. - -Now, you can run your jobs whichever way you want (locally, slurm, grid) and start submitting job! - -## Check the results -It will recursively generate an image based on parameters received from PiCas. Once the jobs are run successfully, you can find the output in the bin directory. -Convert the output file to .png format and display the picture: -``` -convert output_token_6 output_token_6.png # replace with your output filename -display output_token_6.png -``` diff --git a/docs/quick-example.md b/docs/quick-example.md deleted file mode 100644 index 7bf8540..0000000 --- a/docs/quick-example.md +++ /dev/null @@ -1,152 +0,0 @@ -PiCaS quick example -============ - -To demonstrate how pilot job PiCaS works, this page gives instructions on running a quick example which takes probably a few minutes. The quick example including four main steps: - 1. connect to Picas server - 2. prepare and upload tokens to Picas server - 3. run Picas example pilot job - 4. check the tokens and results - - -## Prerequisite - -Before running the example, please read the README.md in [Picas Client](https://github.com/sara-nl/picasclient/). The prerequisites are: - * you have installed and tested the Picas client - * you have a Picas account and a Picas database - * there is a Picas token pool server running on CouchDB. - -If you are following a workshop organized by SURF, the last two requirements have already been arranged for you. - - -## Connect to Picas server - -To connect to the Picas server CouchDB, you need to fill in the `examples/picasconfig.py` with the information to log in to your Picas server and the database you want use for storing the work tokens. Specifically, the information needed are: -``` -PICAS_HOST_URL="https://picas.surfsara.nl:6984" -PICAS_DATABASE="" -PICAS_USERNAME="" -PICAS_PASSWORD="" -``` - -Save and exit. Next don't forget to change the permissions of `examples/picasconfig.py`. Run: -``` -cd examples -chmod 600 picasconfig.py -``` - -For the first time using Picas, you need to define "view" logic and create views. CouchDB views are the basic query mechanism in CouchDB and allow you to extract, transform and combine data from different documents stored in the same database. - -To create these views, run: - -``` -python createViews.py -``` -After a few moments, you should be able to find the generated views in [CouchDB web interface](https://picas.surfsara.nl:6984/_utils/#login). Click on your database and you will see the views on the left under `Monitor/Views`. - -![picas views](./docs/picas-views.png) - - - - -## Prepare and upload tokens - -Next you need to send some tokens containing work to the Picas server. For a quick example with fast running jobs, a `quickExample.txt` file is prepared containing three tokens. Run: -``` -python pushTokens.py quickExample.txt -``` - -## Run Picas example - -In principle, the pilot jobs can be sent to any machine that can run Picas client. For this Picas quick example, we provide instructions on running locally (laptop, cluster login), to a slurm job scheduler and the [Grid](https://www.egi.eu/). - -### Running locally - -To run the example locally, run from the `examples` directory: - -``` -python local-example.py -``` - -If all goes well you should see output like: - -``` ------------------------ -Working on token: token_0 -_id token_0 -_rev 4-8b04da64c0a536bb88a3cdebe12e0a87 -type token -lock 1692692693 -done 0 -hostname xxxxxxxxxxxxxxxxxxxxxxx -scrub_count 0 -input echo "bash-echo" -exit_code 0 ------------------------ -``` - -The token in the database will have attachments with the regular and error output of the terminal. There will find the output file `logs_token_0.out`, containing the output of the input command: - -``` -echo "bash-echo" ->>> bash-echo -``` - -Once the script is running, it will start polling the Picas server for work. Once the work is complete, the script will finish. - -Tokens have status, which will go from "todo" to "done" once the work has been completed (or "failed" if the work fails). To do more work, you will have to add new tokens that are not in a "done" state yet, otherwise the example script will just stop after finding no more work to do. - -### Running on a cluster with Slurm - -To start the slurm job which runs the PiCaS client, run the `slurm-example.sh` from the `examples` directory: - -``` -sbatch slurm-example.sh -``` - -Now in a slurm job array the work will be performed (you can set the number of array jobs in the script at `--array`) and each job will start polling the CouchDB instance for work. Once the work is complete, the slurm job will finish. -If you are interested, you can look into scripts `examples/local-example.py` and `examples/process_task.sh` to check what the actual work is. - -### Running on the Grid - -On the grid, in our screnario, you need to supply the entire environment through the sandbox (a more grid-native CVMFS example is available in the [picas-profile](https://github.com/sara-nl/picas-profile) repository). The binaries and python code need to be in this sandbox. -First we need to create a tar of the picas code, so that it can be sent to the Grid: - -``` -tar cfv grid-sandbox/picas.tar ../picas/ -``` - -Secondly, the CouchDB python API needs to be available too, so download and extract it: - -``` -wget https://files.pythonhosted.org/packages/7c/c8/f94a107eca0c178e5d74c705dad1a5205c0f580840bd1b155cd8a258cb7c/CouchDB-1.2.tar.gz -``` - -Now you can start the example from a grid login node with (in this case DIRAC is used for job submission): - -``` -dirac-wms-job-submit grid-example.jdl -``` - -And the status and output can be retrieved with DIRAC commands, while in the token you see the status of the token and the tokens' attachments contain the log files. Once all tokens have been processed (this can be seen in the CouchDB instance) the grid job will finish. - -As we have seen, through PiCaS you have a single interface that can store tokens with work to be done (the CouchDB instance). Then on any machine where you can deploy the PiCaS client, one can perform the tasks hand. - - -## Check the tokens and results - -While your pilot jobs process tasks, you can keep track of their progress through the CouchDB web interface. There are views installed to see: - - * all the tasks that still need to be done (Monitor/todo) - * the tasks that are locked (Monitor/locked) - * tasks that encountered errors (Monitor/error) - * tasks that are finished (Monitor/done) - -When all your pilot jobs are finished, ideally you'd want all tasks to be 'done'. However, often you will find that not all jobs finished successfully and some are still in a 'locked' or 'error' state. If this happens, you should investigate what went wrong with these jobs. Incidentally, this might be due to errors with the middleware, network or storage. In those cases, you can remove the locks and submitting some new pilot jobs to try again. - -In other cases, there could be errors with your task: maybe you've sent the wrong parameters or forgot to download all necessary input files. Reviewing these failed tasks gives you the possibility to correct them and improve your submission scripts. After that, you could run those tasks again, either by removing their locks or delete older tokens and creating new tokens. After that, you can submit new pilot jobs. - -To delete all the Tokens in a certain view, you can use the `deteleTokens.py` under the `examples` directory. For example to delete all the tokens in todo view, run -``` -python /path-to-script/deleteTokens.py Monitor/todo -``` - diff --git a/docs/token-commands.md b/docs/token-commands.md deleted file mode 100644 index d853889..0000000 --- a/docs/token-commands.md +++ /dev/null @@ -1,52 +0,0 @@ -PiCaS token commands -============ - -This page introduces the most used commands for preparing and editing tokens. - -### Connect to token pool server on CouchDB - -To approach the DB, you have to fill in the `examples/picasconfig.py` with the information to log in to your CouchDB instance and the database you want use for storing the work tokens. Specifically, the information needed are: -``` -PICAS_HOST_URL="https://picas.surfsara.nl:6984" -PICAS_DATABASE="" -PICAS_USERNAME="" -PICAS_PASSWORD="" -``` -### Create views -Once you can approach the server, you have to define "view" logic, so that you can easily view large numbers of tokens and filter on new, running and finished tokens. To create these views, run: - -``` -python createViews.py -``` - -### Create tokens -This example includes a bash script `(./createTokens)` that generates a sensible parameter file, with each line representing a set of parameters that the fractals program can be called with. Without arguments it creates a fairly sensible set of 24 lines of parameters. You can generate different sets of parameters by calling the program with a combination of `-q`, `-d` and `-m` arguments, but at the moment no documentation exists on these. We recommend not to use them for the moment. -``` -./createTokens -``` -After you ran the `createTokens` script you’ll see output similar to the following: -``` -/tmp/tmp.fZ33Kd8wXK -cat /tmp/tmp.fZ33Kd8wXK -``` - -### Upload tokens to the PiCaS server - - -Next you have to send some tokens containing work to the CouchDB instance. You can send two types of work in this example. For very fast running jobs, send the `quickExample.txt` file with: -``` -python pushTokens.py quickExample.txt -``` - -For longer jobs example with a set of 24 lines of parameters. send the file generated in the create tokens step: -``` -python pushTokens.py /tmp/tmp.fZ33Kd8wXK -``` - - -### Delete tokens - -To delete all the Tokens in a certain view, you can use the `deteleTokens.py` under the `examples` directory. For example to delete all the tokens in todo view, run -``` -python /path-to-script/deleteTokens.py Monitor/todo -``` diff --git a/examples/process_task.sh b/examples/process_task.sh index 2be1412..1c3fe2d 100755 --- a/examples/process_task.sh +++ b/examples/process_task.sh @@ -28,6 +28,9 @@ if [[ "$?" != "0" ]]; then exit 1 fi +#Copy output to the remote storage, e.g. +#globus-url-copy file:///${PWD}/${OUTPUT} gsiftp://gridftp.grid.sara.nl:2811/pnfs/grid.sara.nl/data/lsgrid/homer/${OUTPUT} + echo `date` exit 0 diff --git a/examples/quickExample.txt b/examples/quickExample.txt index b1ff1f3..004bc37 100644 --- a/examples/quickExample.txt +++ b/examples/quickExample.txt @@ -1,3 +1,3 @@ -echo 'this is token 1' -echo 'this is token 2' -echo 'this is token 3' +echo 'this is token A' +echo 'this is token B' +echo 'this is token C' From 9fb813542aaa3a594365d0591bbb4187e3cf27ab Mon Sep 17 00:00:00 2001 From: Haili Hu Date: Wed, 4 Dec 2024 14:28:36 +0100 Subject: [PATCH 21/31] Update picas-layer.png --- README.md | 59 ++++++++++++++++++++++++++--------------- docs/picas-layers.png | Bin 34492 -> 35674 bytes docs/picas-layers.pptx | Bin 48751 -> 49011 bytes 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index de30666..5c91b4b 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ picasclient ![CICD](https://github.com/sara-nl/picasclient/actions/workflows/python-app.yml/badge.svg) [![License - MIT](https://img.shields.io/github/license/sara-nl/picasclient)](https://github.com/sara-nl/picasclient/blob/main/LICENSE) -Python client using [CouchDB](https://docs.couchdb.org/en/stable/index.html) as a token pool server. +Python client using [CouchDB](https://docs.couchdb.org/en/stable/index.html) as a token pool server (PiCaS). Installation @@ -12,21 +12,21 @@ Installation Development & Testing --------------------- -To install `picas` source code for development, first clone the repository and then use [`poetry`](https://python-poetry.org/docs/) to install. `poetry` is a tool for dependency managing and packaging in Python. If you don't have `poetry`, install it first with `pipx install poetry`. +To install the PiCaS source code for development, first clone this repository and then use [`poetry`](https://python-poetry.org/docs/) to install. Poetry is a tool for dependency managing and packaging in Python. If you don't have Poetry, install it first with `pipx install poetry`. ``` git clone https://github.com/sara-nl/picasclient.git cd picasclient poetry install --with test ``` -Note that poetry will create a virtual environment if it is not running within an activated virtual environment already. In that case, you will need to run `poetry run` before your commands to execute them within the poetry virtual environment. +Note that Poetry will create a virtual environment if it is not running within an activated virtual environment already. In that case, you will need to run `poetry run` before your commands to execute them within the Poetry virtual environment. -If you prefer not to use `poetry`, then you can install with (in a virtual environment): +If you prefer not to use Poetry, then you can install PiCaS with: ``` pip install -U . pip install flake8 pytest ``` -To test, run +To test, run: ``` flake8 picas tests pytest tests @@ -35,28 +35,33 @@ pytest tests Installing package ------------------ -The latest release of `picas` can be installed as a package from PyPI with: +Alternatively, the latest release of PiCaS can be installed as a package from PyPI with: ``` pip install picas ``` -You can then write your custom Python program to use `picas` based on the examples below. +You can then write your custom Python program to use PiCaS as a library based on the examples below. Examples ======== + The `examples` directory contains two examples how to use the PiCaS client: a short example and a long example. These also include scripts for running locally, on [Spider](https://doc.spider.surfsara.nl/en/latest/Pages/about.html) (SLURM cluster) and the [Grid](https://doc.grid.surfsara.nl/en/latest/). The examples will show how PiCaS provides a single interface that can store tokens (on the CouchDB instance) with work to be done. Then jobs can be sent to any machine where the PiCaS client can be deployed. Prerequisites ------------- +
Get a PiCaS account
+ To run the examples, you need a PiCaS account and access to a database (DB) on the PiCaS CouchDB instance. If you are following a workshop organized by SURF, this has already been arranged for you. If you have a Grid or Spider project at SURF, you can request access through the
Service Desk
+
Connect to the PiCaS server
+ To connect to the PiCaS server, fill `examples/picasconfig.py` with the information needed to log in to your PiCaS account and the database you want to use for storing the work tokens. Specifically, the information needed are: ``` @@ -67,9 +72,11 @@ PICAS_PASSWORD="" ```
+
Create DB Views
+ When you you use the DB for the first time, you need to define "view" logic and create views. CouchDB Views are the primary tool used for querying and reporting on CouchDB documents. For example, you can create views to filter on new, running, finished, and failed job tokens. Some pre-defined views can be created with: ``` @@ -77,11 +84,11 @@ cd examples python createViews.py ``` This will create the following views: - * Monitor/todo: tasks that still need to be done - * Monitor/locked: tasks that are currently running - * Monitor/error: tasks that encountered errors - * Monitor/done: tasks that are finished - * Monitor/overview_total: all tasks and their states + * `Monitor/todo`: tasks that still need to be done + *` Monitor/locked`: tasks that are currently running + * `Monitor/error`: tasks that encountered errors + * `Monitor/done`: tasks that are finished + * `Monitor/overview_total`: all tasks and their states After a few moments, you should be able to find the generated views in the CouchDB web interface. Select your database and you will see the views on the left under `Monitor/Views`: @@ -95,18 +102,21 @@ This example creates fast-running jobs that write a message to standard output.
Create tokens
-The file quickExample.txt contains three lines with commands to be executed. You can generate three job tokens in the PiCaS DB by running: + +The file `quickExample.txt` contains three lines with commands to be executed. You can generate three job tokens in the PiCaS DB by running: ``` python pushTokens.py quickExample.txt ``` -Check the DB if you can find the tokens in the View Monitor/todo. +Check the DB; you should see the tokens in the view `Monitor/todo`.
+
Running locally
+ To run the example locally (e.g. on your laptop) with: ``` @@ -130,7 +140,7 @@ exit_code 0 ----------------------- ``` -The token in the database will have attachments with the standard and error output of the terminal. There you will find the output file `logs_token_0.out`, containing the output of the input command: +The token in the database will have attachments with the standard and error output of the terminal. There you will find the outputfile `logs_token_0.out`, containing the output of the input command: ``` Tue 31 Dec 2024 00:00:00 CET @@ -147,9 +157,11 @@ Once the script is running, it will start polling the Picas server for work. Onc Tokens have a status, which will go from "todo" to "done" once the work has been completed (or "failed" if the work fails). To do more work, you will have to add new tokens that in the "todo" state yet, otherwise the example script will just stop after finding no more work to do. If you are interested, you can look into the scripts `examples/local-example.py` and `examples/process_task.sh` to check what the actual work is.
+
Running on a cluster with SLURM
+ To start the SLURM job which runs the PiCaS client, run the `slurm-example.sh` from the `examples` directory: ``` @@ -159,6 +171,7 @@ sbatch slurm-example.sh Now in a SLURM job array the work will be performed (you can set the number of array jobs in the script at `--array`) and each job will start polling the CouchDB instance for work. Once the work is complete, the SLURM job will finish.
+
Running on the Grid with DIRAC
@@ -183,9 +196,9 @@ dirac-wms-job-submit grid-example.jdl ``` And the status and output can be retrieved with DIRAC commands, while in the token you see the status of the token and the tokens' attachments contain the log files. Once all tokens have been processed (check the DB Views) the grid job will finish. -
+
Check results
@@ -201,7 +214,6 @@ To delete all the Tokens in a certain view, you can use the script `deteleTokens ``` python deleteTokens.py Monitor/error ``` -
@@ -209,6 +221,7 @@ Long example: fractals ---------------------- To get an idea on more realistic, longer running jobs there is also a "fractals" example. The fractals code will recursively generate an image based on parameters received from PiCas. The work can take from 10 seconds up to 30 minutes per token. +
Create tokens
@@ -226,6 +239,7 @@ python pushTokens.py /tmp/tmp.abc123 Now the tokens are available in the database.
+
Prepare code
@@ -235,7 +249,7 @@ Next, the binary for the fractal calculation needs to be built: cc src/fractals.c -o bin/fractals -lm ``` -And finally, the `process_task.sh` code needs to call a different command. Replace +And finally, the `process_task.sh` code needs to call a different command. Replace: ``` bash -c "$INPUT" @@ -248,15 +262,19 @@ bin/fractals -o $OUTPUT $INPUT to ensure that the fractals code is called.
+
Run jobs locally, SLURM cluster or Grid
+ Now, you can run your jobs whichever way you want (locally, SLURM cluster or the Grid), using the general instructions as described above for the quick example!
+
Check results
+ The fractals code will generate an outputfile named `output_token_X`. If the jobs are run locally or on Spider, you can find the outputfile in your work directory. For jobs that are processed on the Grid, you can transfer the outputfile to a remote storage location at the end of your job script `process_task.sh`. To check the results, convert the output file to .png format and display the picture: ``` @@ -266,10 +284,9 @@ display output_token_6.png
- -Picas overview +PiCaS overview ============== -Here is an overview of the layers in picas and how they relate to the code in the `examples` folder. +Below is an overview of the layers in PiCaS and how they relate to the code in the `examples` folder. The scripts `slurm-example.sh` and `grid-example.jdl` are for scheduling jobs on a SLURM cluster and the Grid, respectively. For the Grid, there is an extra script `startpilot.sh` needed to start the job on the GRID Computing Environment (CE). ![picas layers](./docs/picas-layers.png) diff --git a/docs/picas-layers.png b/docs/picas-layers.png index baa83be0516577c96b6cb1923fd09bb869a471c1..0aebeab2a9771dd1185faa1a6b3700ea75011d31 100644 GIT binary patch literal 35674 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

t*r@4~zQfU}_X0b7x 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 C_9UVJ literal 34492 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 diff --git a/docs/picas-layers.pptx b/docs/picas-layers.pptx index c7ec9d8aa86fb8084e9434e8add3df66b6bf1c8b..a7a5bfbd3ad8600875531ffbc4600844dbf74db9 100644 GIT binary patch delta 17124 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 Lh3H-RPuu?i`s Date: Wed, 4 Dec 2024 14:45:25 +0100 Subject: [PATCH 22/31] cleanup --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5c91b4b..9cdafc1 100644 --- a/README.md +++ b/README.md @@ -205,11 +205,11 @@ And the status and output can be retrieved with DIRAC commands, while in the tok While your pilot jobs process tasks, you can keep track of their progress through the CouchDB web interface and the views we created earlier. -When all your pilot jobs are finished, ideally you'd want all tasks to be 'done'. However, often you will find that not all jobs finished successfully and some are still in a 'locked' or 'error' state. If this happens, you should investigate what went wrong with these jobs. Incidentally, this might be due to errors with the middleware, network or storage. In those cases, you can remove the locks and submitting some new pilot jobs to try again. +When all pilot jobs are finished, ideally, you want all tasks to be "done". However, often you will find that not all jobs finished successfully and some are still in a "locked" or "error" state. If this happens, you should investigate what went wrong with these jobs. Incidentally, this might be due to errors with the middleware, network or storage. In those cases, you can remove the locks and submit new pilot jobs to try again. In other cases, there could be errors with your task: maybe you've sent the wrong parameters or forgot to download all necessary input files. Reviewing these failed tasks gives you the possibility to correct them and improve your submission scripts. After that, you could run those tasks again, either by removing their locks or delete older tokens and creating new tokens. After that, you can submit new pilot jobs. -To delete all the Tokens in a certain view, you can use the script `deteleTokens.py`. For example to delete all the tokens in `error` view, run: +To delete all the tokens in a certain view, you can use the script `deteleTokens.py`. For example to delete all the tokens in "error" view, run: ``` python deleteTokens.py Monitor/error @@ -287,6 +287,6 @@ display output_token_6.png PiCaS overview ============== -Below is an overview of the layers in PiCaS and how they relate to the code in the `examples` folder. The scripts `slurm-example.sh` and `grid-example.jdl` are for scheduling jobs on a SLURM cluster and the Grid, respectively. For the Grid, there is an extra script `startpilot.sh` needed to start the job on the GRID Computing Environment (CE). +Below is an overview of the layers in PiCaS and how they relate to the code in the `examples` folder. The scripts `slurm-example.sh` and `grid-example.jdl` are for scheduling jobs on a SLURM cluster and the Grid, respectively. For the Grid, there is an extra script `startpilot.sh` needed to start the job on the GRID Computing Environment. Finally, a job is run with `local-example.py` in the same way when tokens are processed locally. -![picas layers](./docs/picas-layers.png) +![picas layers](./docs/picas-layers.png) \ No newline at end of file From 80aac953444b4f41b43129c47fbc9427eae84a5c Mon Sep 17 00:00:00 2001 From: Haili Hu Date: Wed, 4 Dec 2024 15:17:01 +0100 Subject: [PATCH 23/31] Update Grid example --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 9cdafc1..05870e0 100644 --- a/README.md +++ b/README.md @@ -161,8 +161,7 @@ Tokens have a status, which will go from "todo" to "done" once the work has been

Running on a cluster with SLURM
- -To start the SLURM job which runs the PiCaS client, run the `slurm-example.sh` from the `examples` directory: +You can run this example on a login node of a SLURM cluster, e.g. Spider at SURF. To start the SLURM job which runs the PiCaS client, submit the `slurm-example.sh` script with: ``` sbatch slurm-example.sh @@ -176,7 +175,9 @@ Now in a SLURM job array the work will be performed (you can set the number of a Running on the Grid with DIRAC
-On the grid, in our screnario, you need to supply the entire environment through the sandbox (a more grid-native CVMFS example is available in the [picas-profile](https://github.com/sara-nl/picas-profile) repository). The binaries and python code need to be in this sandbox. +In order to run this example on the Grid, you need the three [Grid Prerequisites](https://doc.grid.surfsara.nl/en/latest/Pages/Basics/prerequisites.html#prerequisites): User Interface (UI) machine, Grid certificate, VO membership. + +On the Grid, in our scenario, you need to supply the entire environment through the sandbox (a more grid-native CVMFS example is available in the [picas-profile](https://github.com/sara-nl/picas-profile) repository). The binaries and python code need to be in this sandbox. First we need to create a tar of the picas code, so that it can be sent to the Grid: ``` @@ -186,16 +187,16 @@ tar cfv grid-sandbox/picas.tar ../picas/ Secondly, the CouchDB python API needs to be available too, so download and extract it: ``` -wget https://files.pythonhosted.org/packages/7c/c8/f94a107eca0c178e5d74c705dad1a5205c0f580840bd1b155cd8a258cb7c/CouchDB-1.2.tar.gz +wget https://files.pythonhosted.org/packages/7c/c8/f94a107eca0c178e5d74c705dad1a5205c0f580840bd1b155cd8a258cb7c/CouchDB-1.2.tar.gz -P grid-sandbox ``` -Now you can start the example from a grid login node with (in this case DIRAC is used for job submission): +Now you can start the example from the Grid UI with (in this case [DIRAC](https://dirac.readthedocs.io/en/latest/index.html) is used for job submission): ``` dirac-wms-job-submit grid-example.jdl ``` -And the status and output can be retrieved with DIRAC commands, while in the token you see the status of the token and the tokens' attachments contain the log files. Once all tokens have been processed (check the DB Views) the grid job will finish. +The status and output can be retrieved with DIRAC commands, while in the token you see the token status and the token attachments contain the log files. Once all tokens have been processed (check the DB views) the Grid job will finish. For more Grid-specific information, see the [Grid documentation](https://doc.grid.surfsara.nl/en/latest/index.html).
From 91b3425b3c51d8ce1c2dd2be92071762583c84f8 Mon Sep 17 00:00:00 2001 From: Haili Hu Date: Wed, 4 Dec 2024 19:47:08 +0100 Subject: [PATCH 24/31] Update README.md --- README.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 05870e0..ed562d4 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ Prerequisites Get a PiCaS account
-To run the examples, you need a PiCaS account and access to a database (DB) on the PiCaS CouchDB instance. If you are following a workshop organized by SURF, this has already been arranged for you. If you have a Grid or Spider project at SURF, you can request access through the Service Desk +To run the examples, you need a PiCaS account and access to a database (DB) on the PiCaS CouchDB instance. If you are following a workshop organized by SURF, this has already been arranged for you. If you have a Grid or Spider project at SURF, you can request access through the Service Desk.
@@ -70,6 +70,7 @@ PICAS_DATABASE="" PICAS_USERNAME="" PICAS_PASSWORD="" ``` +Note that `PICAS_HOST_URL` can be different if your project has its own CouchDB instance. @@ -77,7 +78,7 @@ PICAS_PASSWORD="" Create DB Views
-When you you use the DB for the first time, you need to define "view" logic and create views. CouchDB Views are the primary tool used for querying and reporting on CouchDB documents. For example, you can create views to filter on new, running, finished, and failed job tokens. Some pre-defined views can be created with: +When you you use the DB for the first time, you need to define "view" logic and create views. CouchDB views are the primary tool used for querying and reporting on CouchDB documents. For example, you can create views to filter on new, running, finished, and failed job tokens. Some pre-defined views can be created with: ``` cd examples @@ -85,7 +86,7 @@ python createViews.py ``` This will create the following views: * `Monitor/todo`: tasks that still need to be done - *` Monitor/locked`: tasks that are currently running + * ` Monitor/locked`: tasks that are currently running * `Monitor/error`: tasks that encountered errors * `Monitor/done`: tasks that are finished * `Monitor/overview_total`: all tasks and their states @@ -123,7 +124,7 @@ To run the example locally (e.g. on your laptop) with: python local-example.py ``` -If all goes well you should see output like: +If all goes well, you should see output like: ``` ----------------------- @@ -152,7 +153,7 @@ this is token A Tue 31 Dec 2024 00:00:00 CET ``` -Once the script is running, it will start polling the Picas server for work. Once the work is complete, the script will finish. +Once the script is running, it will start polling the PiCaS server for work. Once the work is complete, the script will finish. Tokens have a status, which will go from "todo" to "done" once the work has been completed (or "failed" if the work fails). To do more work, you will have to add new tokens that in the "todo" state yet, otherwise the example script will just stop after finding no more work to do. If you are interested, you can look into the scripts `examples/local-example.py` and `examples/process_task.sh` to check what the actual work is. @@ -167,7 +168,7 @@ You can run this example on a login node of a SLURM cluster, e.g. Spider at SURF sbatch slurm-example.sh ``` -Now in a SLURM job array the work will be performed (you can set the number of array jobs in the script at `--array`) and each job will start polling the CouchDB instance for work. Once the work is complete, the SLURM job will finish. +Now the work will be performed in parallel by a SLURM job array, and each job will start polling the CouchDB instance for work. Once the work is complete, the SLURM job will finish. You can set the number of array jobs in the script with `--array`. For more information on SLURM, see the [SLURM documentation](https://slurm.schedmd.com/). @@ -288,6 +289,9 @@ display output_token_6.png PiCaS overview ============== -Below is an overview of the layers in PiCaS and how they relate to the code in the `examples` folder. The scripts `slurm-example.sh` and `grid-example.jdl` are for scheduling jobs on a SLURM cluster and the Grid, respectively. For the Grid, there is an extra script `startpilot.sh` needed to start the job on the GRID Computing Environment. Finally, a job is run with `local-example.py` in the same way when tokens are processed locally. +Below is an overview of the layers in PiCaS and how they relate to the code in the `examples` folder. +* The scripts `slurm-example.sh` and `grid-example.jdl` are for scheduling jobs on a SLURM cluster and the Grid, respectively. +* For the Grid, there is an extra script `startpilot.sh` needed to start the job on the Grid Computing Environment. +* Finally, a job is run with `local-example.py` in the same way when tokens are processed locally. -![picas layers](./docs/picas-layers.png) \ No newline at end of file +![picas layers](./docs/picas-layers.png) From 346b9ae0f212ab352f9f8c179277aee06a4e208a Mon Sep 17 00:00:00 2001 From: Haili Hu Date: Thu, 5 Dec 2024 13:17:49 +0100 Subject: [PATCH 25/31] Update README.md --- README.md | 65 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index ed562d4..30107f9 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ picasclient ![CICD](https://github.com/sara-nl/picasclient/actions/workflows/python-app.yml/badge.svg) [![License - MIT](https://img.shields.io/github/license/sara-nl/picasclient)](https://github.com/sara-nl/picasclient/blob/main/LICENSE) -Python client using [CouchDB](https://docs.couchdb.org/en/stable/index.html) as a token pool server (PiCaS). +Python client using [CouchDB](https://docs.couchdb.org/en/stable/index.html) as a token pool server (PiCaS). PiCaS is a [pilot job framework](https://doc.spider.surfsara.nl/en/latest/Pages/pilotjob_picas.html). Pilot jobs, instead of executing a task directly, contact a central server to be assigned a task and get all the information needed for executing this task. Installation @@ -12,7 +12,7 @@ Installation Development & Testing --------------------- -To install the PiCaS source code for development, first clone this repository and then use [`poetry`](https://python-poetry.org/docs/) to install. Poetry is a tool for dependency managing and packaging in Python. If you don't have Poetry, install it first with `pipx install poetry`. +To install the PiCaS source code for development, first clone this repository and then use [Poetry](https://python-poetry.org/docs/) to install. Poetry is a tool for dependency managing and packaging in Python. If you don't have Poetry, install it first with `pipx install poetry`. ``` git clone https://github.com/sara-nl/picasclient.git cd picasclient @@ -45,7 +45,7 @@ You can then write your custom Python program to use PiCaS as a library based on Examples ======== -The `examples` directory contains two examples how to use the PiCaS client: a short example and a long example. These also include scripts for running locally, on [Spider](https://doc.spider.surfsara.nl/en/latest/Pages/about.html) (SLURM cluster) and the [Grid](https://doc.grid.surfsara.nl/en/latest/). The examples will show how PiCaS provides a single interface that can store tokens (on the CouchDB instance) with work to be done. Then jobs can be sent to any machine where the PiCaS client can be deployed. +The `examples` directory contains two examples how to use the PiCaS client: a short example and a long example. These also include scripts for running locally, on [Spider](https://doc.spider.surfsara.nl/en/latest/Pages/about.html) (SLURM cluster) and the [Grid](https://doc.grid.surfsara.nl/en/latest/). The examples will show how PiCaS provides a single interface that can store tokens (on the CouchDB instance) with work to be done. Then pilot jobs can be sent to any machine where the PiCaS client can be deployed. Prerequisites ------------- @@ -54,7 +54,7 @@ Prerequisites Get a PiCaS account
-To run the examples, you need a PiCaS account and access to a database (DB) on the PiCaS CouchDB instance. If you are following a workshop organized by SURF, this has already been arranged for you. If you have a Grid or Spider project at SURF, you can request access through the Service Desk. +To run the examples, you need a PiCaS account and access to a database (DB) on the PiCaS CouchDB instance. If you are following a workshop organized by SURF, this has already been arranged for you. If you have a Grid or Spider project at SURF, you can request access through the Service Desk @@ -86,7 +86,7 @@ python createViews.py ``` This will create the following views: * `Monitor/todo`: tasks that still need to be done - * ` Monitor/locked`: tasks that are currently running + * `Monitor/locked`: tasks that are currently running * `Monitor/error`: tasks that encountered errors * `Monitor/done`: tasks that are finished * `Monitor/overview_total`: all tasks and their states @@ -162,13 +162,14 @@ Tokens have a status, which will go from "todo" to "done" once the work has been
Running on a cluster with SLURM
+ You can run this example on a login node of a SLURM cluster, e.g. Spider at SURF. To start the SLURM job which runs the PiCaS client, submit the `slurm-example.sh` script with: ``` sbatch slurm-example.sh ``` -Now the work will be performed in parallel by a SLURM job array, and each job will start polling the CouchDB instance for work. Once the work is complete, the SLURM job will finish. You can set the number of array jobs in the script with `--array`. For more information on SLURM, see the [SLURM documentation](https://slurm.schedmd.com/). +Now the work will be performed in parallel by a SLURM job array, and each job will start polling the CouchDB instance for work. Once the work is complete, the SLURM job will finish. You can set the number of array jobs in the script with `--array`. For more information on SLURM job scheduler, see the [SLURM documentation](https://slurm.schedmd.com/).
@@ -178,8 +179,7 @@ Now the work will be performed in parallel by a SLURM job array, and each job wi In order to run this example on the Grid, you need the three [Grid Prerequisites](https://doc.grid.surfsara.nl/en/latest/Pages/Basics/prerequisites.html#prerequisites): User Interface (UI) machine, Grid certificate, VO membership. -On the Grid, in our scenario, you need to supply the entire environment through the sandbox (a more grid-native CVMFS example is available in the [picas-profile](https://github.com/sara-nl/picas-profile) repository). The binaries and python code need to be in this sandbox. -First we need to create a tar of the picas code, so that it can be sent to the Grid: +On the Grid, you can install software you need either on [Softdrive](https://doc.grid.surfsara.nl/en/stable/Pages/Advanced/grid_software.html#softdrive), download it during job execution, or provide it through the "input sandbox". In this example, we supply the entire environment through the sandbox. The binaries and python code need to be in this sandbox. First we need to create a tar of the PiCaS code, so that it can be sent to the Grid. On you Grid UI, run: ``` tar cfv grid-sandbox/picas.tar ../picas/ @@ -191,13 +191,12 @@ Secondly, the CouchDB python API needs to be available too, so download and extr wget https://files.pythonhosted.org/packages/7c/c8/f94a107eca0c178e5d74c705dad1a5205c0f580840bd1b155cd8a258cb7c/CouchDB-1.2.tar.gz -P grid-sandbox ``` -Now you can start the example from the Grid UI with (in this case [DIRAC](https://dirac.readthedocs.io/en/latest/index.html) is used for job submission): +Now you can start the example from the Grid UI with: ``` dirac-wms-job-submit grid-example.jdl ``` - -The status and output can be retrieved with DIRAC commands, while in the token you see the token status and the token attachments contain the log files. Once all tokens have been processed (check the DB views) the Grid job will finish. For more Grid-specific information, see the [Grid documentation](https://doc.grid.surfsara.nl/en/latest/index.html). +In this case [DIRAC](https://dirac.readthedocs.io/en/latest/index.html) is used for job submission. The status and output can be retrieved with DIRAC commands, while in the token you see the token status and the token attachments contain the log files. Once all tokens have been processed (check the DB views) the Grid job will finish. For more Grid-specific information, see the [Grid documentation](https://doc.grid.surfsara.nl/en/latest/index.html). @@ -221,7 +220,7 @@ python deleteTokens.py Monitor/error Long example: fractals ---------------------- -To get an idea on more realistic, longer running jobs there is also a "fractals" example. The fractals code will recursively generate an image based on parameters received from PiCas. The work can take from 10 seconds up to 30 minutes per token. +To get an idea on more realistic, longer running jobs there is also a "fractals" example. The fractals code will recursively generate an image based on parameters received from PiCaS. The work can take from 10 seconds up to 30 minutes per token.
@@ -277,12 +276,48 @@ Now, you can run your jobs whichever way you want (locally, SLURM cluster or the Check results
-The fractals code will generate an outputfile named `output_token_X`. If the jobs are run locally or on Spider, you can find the outputfile in your work directory. For jobs that are processed on the Grid, you can transfer the outputfile to a remote storage location at the end of your job script `process_task.sh`. To check the results, convert the output file to .png format and display the picture: +The fractals code will generate an outputfile named `output_token_X`. If the jobs are run locally or on Spider, you can find the outputfile in your work directory. For jobs that are processed on the Grid, you can transfer the outputfile to a remote storage location at the end of your job script `process_task.sh`. To check the results, convert the output file to PNG format and display the picture: ``` -convert output_token_6 output_token_6.png # replace with your output filename -display output_token_6.png +convert output_token_X output_token_X.png +display output_token_X.png +``` +
+ + +Advanced features +------------- + + +
+Stop criteria +
+ +In the main program of `local-example.py`, the work is executed by this line: + +``` +actor.run(max_token_time=1800, max_total_time=3600, max_tasks=10, max_scrub=2) +``` +The arguments in this function allow the user to speficy criteria to stop processing: +* max_token_time: maximum time (seconds) to run a single token before going stopping +* max_total_time: maximum time (seconds) to run picas before stopping +* max_tasks: number of tasks that are performed before stopping +* max_scrub: number of times a token can be reset ('scrubbed') after failing +So in our example: if a token is not finished in 30 minutes, the token is "scrubbed" (i.e. reset to "todo"), and the next token will be fetched. If a token is scrubbed more than 2 times, it will be set to "error". Nore more tokens will be processed after one hour or after 10 tokens have finished, whatever happens earlier. + +Users can even define a custom `stop_function` (with `**kwargs`) and pass that to `actors.run()`. See for details, `picas/actors.py`. + +
+ +
+Change iterator +
+ +Normally, if there are no more tokens in the DB to be processed, the pilot job will stop. However, you can tell the pilot job to continue polling the PiCaS server for work untill `max_total_time` has been reached. This is be done by uncommenting this line in `local-example.py`, in the function `ExampleActor.__init()`: +``` +self.iterator = EndlessViewIterator(self.iterator) ``` +
From f943058aad769c364c4b1eeff1e2c0c76f9f1b6a Mon Sep 17 00:00:00 2001 From: Haili Hu Date: Thu, 5 Dec 2024 13:25:42 +0100 Subject: [PATCH 26/31] Update local-example.py --- README.md | 10 +++++----- examples/local-example.py | 7 +++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 30107f9..ed356a0 100644 --- a/README.md +++ b/README.md @@ -299,10 +299,10 @@ In the main program of `local-example.py`, the work is executed by this line: actor.run(max_token_time=1800, max_total_time=3600, max_tasks=10, max_scrub=2) ``` The arguments in this function allow the user to speficy criteria to stop processing: -* max_token_time: maximum time (seconds) to run a single token before going stopping -* max_total_time: maximum time (seconds) to run picas before stopping -* max_tasks: number of tasks that are performed before stopping -* max_scrub: number of times a token can be reset ('scrubbed') after failing +* `max_token_time`: maximum time (seconds) to run a single token before going stopping +* `max_total_time`: maximum time (seconds) to run picas before stopping +* `max_tasks`: number of tasks that are performed before stopping +* `max_scrub`: number of times a token can be reset ("scrubbed") after failing So in our example: if a token is not finished in 30 minutes, the token is "scrubbed" (i.e. reset to "todo"), and the next token will be fetched. If a token is scrubbed more than 2 times, it will be set to "error". Nore more tokens will be processed after one hour or after 10 tokens have finished, whatever happens earlier. Users can even define a custom `stop_function` (with `**kwargs`) and pass that to `actors.run()`. See for details, `picas/actors.py`. @@ -329,4 +329,4 @@ Below is an overview of the layers in PiCaS and how they relate to the code in t * For the Grid, there is an extra script `startpilot.sh` needed to start the job on the Grid Computing Environment. * Finally, a job is run with `local-example.py` in the same way when tokens are processed locally. -![picas layers](./docs/picas-layers.png) +![picas layers](./docs/picas-layers.png) \ No newline at end of file diff --git a/examples/local-example.py b/examples/local-example.py index c97b9f1..afdd804 100755 --- a/examples/local-example.py +++ b/examples/local-example.py @@ -35,7 +35,7 @@ class ExampleActor(RunActor): def __init__(self, db, modifier, view="todo", **viewargs): super(ExampleActor, self).__init__(db, view=view, **viewargs) self.timer = Timer() - self.iterator = EndlessViewIterator(self.iterator) + # self.iterator = EndlessViewIterator(self.iterator) self.modifier = modifier self.client = db @@ -48,8 +48,7 @@ def process_task(self, token): print("-----------------------") # Start running the main job, the logging is done internally and saved below - # /usr/bin/time -v ./process_task.sh [input] [tokenid] - command = ["/usr/bin/time", "-v", "./process_task.sh", token['input'], token['_id']] + command = ["/usr/bin/time", "./process_task.sh", token['input'], token['_id']] out = execute(command) logsout = f"logs_{token['_id']}.out" @@ -88,7 +87,7 @@ def main(): # Create actor actor = ExampleActor(client, modifier) # Start work! - actor.run(max_token_time=10, max_total_time=100, max_tasks=10, max_scrub=2) + actor.run(max_token_time=10, max_total_time=3600, max_tasks=10, max_scrub=2) if __name__ == '__main__': main() From c97373a0b92a34bb671f3506b941c3be44fe5813 Mon Sep 17 00:00:00 2001 From: Haili Hu Date: Thu, 5 Dec 2024 13:31:43 +0100 Subject: [PATCH 27/31] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ed356a0..d0f7956 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ picasclient ![CICD](https://github.com/sara-nl/picasclient/actions/workflows/python-app.yml/badge.svg) [![License - MIT](https://img.shields.io/github/license/sara-nl/picasclient)](https://github.com/sara-nl/picasclient/blob/main/LICENSE) -Python client using [CouchDB](https://docs.couchdb.org/en/stable/index.html) as a token pool server (PiCaS). PiCaS is a [pilot job framework](https://doc.spider.surfsara.nl/en/latest/Pages/pilotjob_picas.html). Pilot jobs, instead of executing a task directly, contact a central server to be assigned a task and get all the information needed for executing this task. +Python client using [CouchDB](https://docs.couchdb.org/en/stable/index.html) as a token pool server (PiCaS). PiCaS is a [pilot job framework](https://doc.spider.surfsara.nl/en/latest/Pages/pilotjob_picas.html). Installation @@ -45,7 +45,7 @@ You can then write your custom Python program to use PiCaS as a library based on Examples ======== -The `examples` directory contains two examples how to use the PiCaS client: a short example and a long example. These also include scripts for running locally, on [Spider](https://doc.spider.surfsara.nl/en/latest/Pages/about.html) (SLURM cluster) and the [Grid](https://doc.grid.surfsara.nl/en/latest/). The examples will show how PiCaS provides a single interface that can store tokens (on the CouchDB instance) with work to be done. Then pilot jobs can be sent to any machine where the PiCaS client can be deployed. +The `examples` directory contains two examples how to use the PiCaS client: a short example and a long example. These also include scripts for running locally, on [Spider](https://doc.spider.surfsara.nl/en/latest/Pages/about.html) (SLURM cluster) and the [Grid](https://doc.grid.surfsara.nl/en/latest/). The examples will show how PiCaS provides a single interface that can store tokens (on the CouchDB instance) with work to be done. Then pilot jobs can be sent to any machine where the PiCaS client can be deployed. Pilot jobs, instead of executing a task directly, contact a central server to be assigned a task and get all the information needed for executing this task. Prerequisites ------------- @@ -54,7 +54,7 @@ Prerequisites Get a PiCaS account
-To run the examples, you need a PiCaS account and access to a database (DB) on the PiCaS CouchDB instance. If you are following a workshop organized by SURF, this has already been arranged for you. If you have a Grid or Spider project at SURF, you can request access through the Service Desk +To run the examples, you need a PiCaS account and access to a database (DB) on the PiCaS CouchDB instance. If you are following a workshop organized by SURF, this has already been arranged for you. If you have a Grid or Spider project at SURF, you can request access through the Service Desk. @@ -313,7 +313,7 @@ Users can even define a custom `stop_function` (with `**kwargs`) and pass that t Change iterator
-Normally, if there are no more tokens in the DB to be processed, the pilot job will stop. However, you can tell the pilot job to continue polling the PiCaS server for work untill `max_total_time` has been reached. This is be done by uncommenting this line in `local-example.py`, in the function `ExampleActor.__init()`: +Normally, if there are no more tokens in the DB to be processed, the pilot job will stop. However, you can tell the pilot job to continue polling the PiCaS server for work untill `max_total_time` has been reached. This is done by uncommenting this line in `local-example.py`, in the function `ExampleActor.__init()`: ``` self.iterator = EndlessViewIterator(self.iterator) ``` @@ -329,4 +329,4 @@ Below is an overview of the layers in PiCaS and how they relate to the code in t * For the Grid, there is an extra script `startpilot.sh` needed to start the job on the Grid Computing Environment. * Finally, a job is run with `local-example.py` in the same way when tokens are processed locally. -![picas layers](./docs/picas-layers.png) \ No newline at end of file +![picas layers](./docs/picas-layers.png) From 0ff92f4eb74801a20cf3707c03f7b7a5b060009b Mon Sep 17 00:00:00 2001 From: Haili Hu Date: Fri, 6 Dec 2024 10:33:46 +0100 Subject: [PATCH 28/31] Update README.md --- README.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d0f7956..f5c8760 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ Check the DB; you should see the tokens in the view `Monitor/todo`. Running locally
-To run the example locally (e.g. on your laptop) with: +To run the example locally (e.g. on your laptop): ``` python local-example.py @@ -153,9 +153,9 @@ this is token A Tue 31 Dec 2024 00:00:00 CET ``` -Once the script is running, it will start polling the PiCaS server for work. Once the work is complete, the script will finish. +Once the script is running, it will start polling the PiCaS server for work. A pilot job will not die after it has completed a task, but immediately ask for another one. It will keep asking for new jobs, until all work is done, or the maximum time is up. -Tokens have a status, which will go from "todo" to "done" once the work has been completed (or "failed" if the work fails). To do more work, you will have to add new tokens that in the "todo" state yet, otherwise the example script will just stop after finding no more work to do. If you are interested, you can look into the scripts `examples/local-example.py` and `examples/process_task.sh` to check what the actual work is. +Tokens have a status, which will go from "todo" to "done" once the work has been completed (or "error" if the work fails). To do more work, you will have to add new tokens that in the "todo" state yet, otherwise the example script will just stop after finding no more work to do. If you are interested, you can look into the scripts `examples/local-example.py` and `examples/process_task.sh` to check what the actual work is. @@ -206,9 +206,7 @@ In this case [DIRAC](https://dirac.readthedocs.io/en/latest/index.html) is used While your pilot jobs process tasks, you can keep track of their progress through the CouchDB web interface and the views we created earlier. -When all pilot jobs are finished, ideally, you want all tasks to be "done". However, often you will find that not all jobs finished successfully and some are still in a "locked" or "error" state. If this happens, you should investigate what went wrong with these jobs. Incidentally, this might be due to errors with the middleware, network or storage. In those cases, you can remove the locks and submit new pilot jobs to try again. - -In other cases, there could be errors with your task: maybe you've sent the wrong parameters or forgot to download all necessary input files. Reviewing these failed tasks gives you the possibility to correct them and improve your submission scripts. After that, you could run those tasks again, either by removing their locks or delete older tokens and creating new tokens. After that, you can submit new pilot jobs. +When all pilot jobs are finished, ideally, you want all tasks to be "done". However, often you will find that not all jobs finished successfully and some are still in a "locked" or "error" state. If this happens, you should investigate what went wrong with these jobs. Incidentally, this might be due to errors with the middleware, network or storage. In other cases, there could be errors with your task: maybe you've sent the wrong parameters or forgot to download all necessary input files. Reviewing these failed tasks gives you the possibility to correct them and improve your submission scripts. After that, you could run those tasks again, either by removing their locks or delete older tokens and creating new tokens. After that, you can submit new pilot jobs. To delete all the tokens in a certain view, you can use the script `deteleTokens.py`. For example to delete all the tokens in "error" view, run: @@ -299,7 +297,7 @@ In the main program of `local-example.py`, the work is executed by this line: actor.run(max_token_time=1800, max_total_time=3600, max_tasks=10, max_scrub=2) ``` The arguments in this function allow the user to speficy criteria to stop processing: -* `max_token_time`: maximum time (seconds) to run a single token before going stopping +* `max_token_time`: maximum time (seconds) to run a single token before stopping and going to next token * `max_total_time`: maximum time (seconds) to run picas before stopping * `max_tasks`: number of tasks that are performed before stopping * `max_scrub`: number of times a token can be reset ("scrubbed") after failing From faed7e41f96ad7657071d4247272b16528daed0a Mon Sep 17 00:00:00 2001 From: Haili Hu Date: Mon, 9 Dec 2024 13:32:01 +0100 Subject: [PATCH 29/31] Added examples/resetTokens.py --- README.md | 63 +++++++++++++++++++++++-------------- examples/deleteTokens.py | 5 ++- examples/resetTokens.py | 68 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 26 deletions(-) create mode 100644 examples/resetTokens.py diff --git a/README.md b/README.md index f5c8760..e425b97 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,10 @@ picasclient Python client using [CouchDB](https://docs.couchdb.org/en/stable/index.html) as a token pool server (PiCaS). PiCaS is a [pilot job framework](https://doc.spider.surfsara.nl/en/latest/Pages/pilotjob_picas.html). -Installation -============ +# Installation -Development & Testing ---------------------- + +## Development & Testing To install the PiCaS source code for development, first clone this repository and then use [Poetry](https://python-poetry.org/docs/) to install. Poetry is a tool for dependency managing and packaging in Python. If you don't have Poetry, install it first with `pipx install poetry`. ``` @@ -33,8 +32,8 @@ pytest tests ``` -Installing package ------------------- +## Installing package + Alternatively, the latest release of PiCaS can be installed as a package from PyPI with: ``` pip install picas @@ -42,13 +41,11 @@ pip install picas You can then write your custom Python program to use PiCaS as a library based on the examples below. -Examples -======== +# Examples The `examples` directory contains two examples how to use the PiCaS client: a short example and a long example. These also include scripts for running locally, on [Spider](https://doc.spider.surfsara.nl/en/latest/Pages/about.html) (SLURM cluster) and the [Grid](https://doc.grid.surfsara.nl/en/latest/). The examples will show how PiCaS provides a single interface that can store tokens (on the CouchDB instance) with work to be done. Then pilot jobs can be sent to any machine where the PiCaS client can be deployed. Pilot jobs, instead of executing a task directly, contact a central server to be assigned a task and get all the information needed for executing this task. -Prerequisites -------------- +## Prerequisites
Get a PiCaS account @@ -97,8 +94,8 @@ After a few moments, you should be able to find the generated views in the -Quick example -------------- +## Quick example + This example creates fast-running jobs that write a message to standard output.
Create tokens @@ -206,18 +203,16 @@ In this case [DIRAC](https://dirac.readthedocs.io/en/latest/index.html) is used While your pilot jobs process tasks, you can keep track of their progress through the CouchDB web interface and the views we created earlier. -When all pilot jobs are finished, ideally, you want all tasks to be "done". However, often you will find that not all jobs finished successfully and some are still in a "locked" or "error" state. If this happens, you should investigate what went wrong with these jobs. Incidentally, this might be due to errors with the middleware, network or storage. In other cases, there could be errors with your task: maybe you've sent the wrong parameters or forgot to download all necessary input files. Reviewing these failed tasks gives you the possibility to correct them and improve your submission scripts. After that, you could run those tasks again, either by removing their locks or delete older tokens and creating new tokens. After that, you can submit new pilot jobs. +When all pilot jobs are finished, ideally, you want all tasks to be "done". However, often you will find that not all jobs finished successfully and some are still in a "locked" or "error" state. If this happens, you should investigate what went wrong with these jobs by checking the attached logfiles. Incidentally, this might be due to errors with the middleware, network or storage. In other cases, there could be errors with your task: maybe you've sent the wrong parameters or forgot to download all necessary input files. Reviewing these failed tasks gives you the possibility to correct them and improve your submission scripts. + +You can re-run failed tasks, either by resetting failed/locked tokens or deleting them and creating new tokens, see [Advanced features](#advanced-features). After that, you can submit new pilot jobs. -To delete all the tokens in a certain view, you can use the script `deteleTokens.py`. For example to delete all the tokens in "error" view, run: -``` -python deleteTokens.py Monitor/error -```
-Long example: fractals ----------------------- +## Long example: fractals + To get an idea on more realistic, longer running jobs there is also a "fractals" example. The fractals code will recursively generate an image based on parameters received from PiCaS. The work can take from 10 seconds up to 30 minutes per token. @@ -283,9 +278,10 @@ display output_token_X.png
-Advanced features -------------- +## Advanced features + +
Stop criteria @@ -307,6 +303,28 @@ Users can even define a custom `stop_function` (with `**kwargs`) and pass that t
+ +
+Resetting and deleting tokens +
+ +To reset tokens in a certain view back to "todo", you can use the script `resetTokens.py`. For example, to reset all locked tokens: + +``` +python resetTokens.py Monitor/locked +``` +This will also increase the "scrub_count" of the tokens. Optionally, one can provide a locktime argument. For example, to reset tokens that have been locked more than 24 hours, run: + +``` +python resetTokens.py Monitor/locked 24 +``` + +If you want to delete all the tokens in a certain view, use the script `deteleTokens.py`. For example, to delete all the tokens in "error" view, run: + +``` +python deleteTokens.py Monitor/error +``` +
Change iterator
@@ -319,8 +337,7 @@ self.iterator = EndlessViewIterator(self.iterator)
-PiCaS overview -============== +# PiCaS overview Below is an overview of the layers in PiCaS and how they relate to the code in the `examples` folder. * The scripts `slurm-example.sh` and `grid-example.jdl` are for scheduling jobs on a SLURM cluster and the Grid, respectively. diff --git a/examples/deleteTokens.py b/examples/deleteTokens.py index cecb134..b90acd1 100644 --- a/examples/deleteTokens.py +++ b/examples/deleteTokens.py @@ -3,7 +3,7 @@ @helpdesk: SURFsara helpdesk usage: python deleteTokens.py [viewname] - e.g. python deleteTokens.py Monitor/todo + e.g. python deleteTokens.py Monitor/error description: Connect to PiCaS server @@ -16,8 +16,7 @@ import picasconfig -def deleteDocs(db, viewname): - # v=db.view("Monitor/todo") +def deleteDocs(db, viewname="Monitor/error"): v = db.view(viewname) for x in v: document = db[x['key']] diff --git a/examples/resetTokens.py b/examples/resetTokens.py new file mode 100644 index 0000000..3b3492e --- /dev/null +++ b/examples/resetTokens.py @@ -0,0 +1,68 @@ +''' + +@helpdesk: SURFsara helpdesk + +usage: python resetTokens.py [viewname] [locktime] + e.g. python resetTokens.py Monitor/locked 72 + +description: + Connect to PiCaS server + Reset all Tokens in [viewname] View that have been locked more than [hours] hours, + defaults to 0 hours to reset all tokens +''' + +import sys + +import couchdb +from time import time +import picasconfig + +def resetDocs(db, viewname="Monitor/locked", locktime=0): + v = db.view(viewname) + max_age = locktime * 3600 + to_update = [] + for x in v: + document = db[x['key']] + age = time() - document["lock"] + print(age) + if (age > max_age): + document['lock'] = 0 + document['done'] = 0 + document['scrub_count'] += 1 + document['hostname'] = '' + document['exit_code'] = '' + if '_attachments' in document: + del document["_attachments"] + to_update.append(document) + db.update(to_update) + print("Number of reset tokens: " + str(len(to_update))) + + +def get_db(): + server = couchdb.Server(picasconfig.PICAS_HOST_URL) + username = picasconfig.PICAS_USERNAME + pwd = picasconfig.PICAS_PASSWORD + server.resource.credentials = (username, pwd) + db = server[picasconfig.PICAS_DATABASE] + return db + + +if __name__ == '__main__': + # Create a connection to the server + db = get_db() + + if len(sys.argv)==1: + sys.exit("Error: No viewname provided. To reset all locked tokens: `python resetTokens.py Monitor/locked`") + elif len(sys.argv)>1: + # reset the Docs in [viewname] + viewname = str(sys.argv[1]) + if len(sys.argv)==2: + print("Warning: No locktime provided. Will reset all tokens in view ", viewname) + input("Press Enter to continue or Ctrl+C to cancel.") + # default: reset all locked tokens + locktime=0 + else: + locktime=float(sys.argv[2]) + + + resetDocs(db, viewname, locktime) From 71140ca96bebaf0a9425c0b4e7937b806a7c262d Mon Sep 17 00:00:00 2001 From: Haili Hu Date: Mon, 9 Dec 2024 13:33:38 +0100 Subject: [PATCH 30/31] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e425b97..0d63a96 100644 --- a/README.md +++ b/README.md @@ -324,6 +324,7 @@ If you want to delete all the tokens in a certain view, use the script `deteleTo ``` python deleteTokens.py Monitor/error ``` +
Change iterator From f2cc1b0a369937872c3fe6db4d0d6e101113cca9 Mon Sep 17 00:00:00 2001 From: Haili Hu Date: Mon, 9 Dec 2024 16:28:54 +0100 Subject: [PATCH 31/31] Update local-example.py Increase max_token_time for long example --- examples/local-example.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/local-example.py b/examples/local-example.py index afdd804..bae4ce9 100755 --- a/examples/local-example.py +++ b/examples/local-example.py @@ -87,7 +87,7 @@ def main(): # Create actor actor = ExampleActor(client, modifier) # Start work! - actor.run(max_token_time=10, max_total_time=3600, max_tasks=10, max_scrub=2) + actor.run(max_token_time=1800, max_total_time=3600, max_tasks=10, max_scrub=2) if __name__ == '__main__': main()
+Get a PiCaS account +
+To run the examples, you need a PiCaS account and access to a database (DB) on the PiCaS CouchDB instance. If you are following a workshop organized by SURF, this has already been arranged for you. If you are have a Grid or Spider project at SURF, you can request access through the
Service Desk +