diff --git a/example/hello-world-intel-mpi/README.md b/example/hello-world-intel-mpi/README.md new file mode 100644 index 0000000..7a78847 --- /dev/null +++ b/example/hello-world-intel-mpi/README.md @@ -0,0 +1,10 @@ +# Hello World Intel MPI + +This example shows requesting using the intel MPI snippet, which means adding a custom setup and run +command to your code. An hpc-* flavored family is required (which is the default). + +```bash +GOOGLE_PROJECT=myproject +snakemake --jobs 1 --executor googlebatch --googlebatch-region us-central1 --googlebatch-project ${GOOGLE_PROJECT} --default-storage-provider s3 --default-storage-prefix s3://my-snakemake-testing --googlebatch-snippets intel-mpi +``` + diff --git a/example/hello-world-intel-mpi/Snakefile b/example/hello-world-intel-mpi/Snakefile new file mode 100644 index 0000000..6c66c3f --- /dev/null +++ b/example/hello-world-intel-mpi/Snakefile @@ -0,0 +1,57 @@ +# https://github.com/snakemake/snakemake/blob/main/tests/test_slurm_mpi/Snakefile +# Note that in reality, the mpi, account, and partition resources should be specified +# via --default-resources, in order to keep such infrastructure specific details out of the +# workflow definition. + + +localrules: + all, + clean, + copy, + +rule all: + input: + "pi.calc", + +rule clean: + shell: + "rm -f pi.calc" + +rule copy: + input: + local("pi_MPI.c"), + output: + "pi_MPI.c", + log: + "logs/copy.log", + resources: + mem_mb=0, + shell: + "cp {input} {output} &> {log}" + +rule compile: + input: + "pi_MPI.c", + output: + "pi_MPI", + log: + "logs/compile.log", + resources: + mem_mb=0, + shell: + "mpicc -o {output} {input} &> {log}" + +rule calc_pi: + input: + "pi_MPI", + output: + "pi.calc", + log: + "logs/calc_pi.log", + resources: + mem_mb=0, + tasks=1, + mpi="mpiexec", + shell: + "chmod +x {input};" + "{resources.mpi} -hostfile $BATCH_HOSTS_FILE -n {resources.tasks} {input} 10 > {output};" diff --git a/example/hello-world-intel-mpi/pi_MPI.c b/example/hello-world-intel-mpi/pi_MPI.c new file mode 100644 index 0000000..7f0a57f --- /dev/null +++ b/example/hello-world-intel-mpi/pi_MPI.c @@ -0,0 +1,66 @@ +#include +#include +#include "stdlib.h" +#include "mpi.h" + + +double f(double x){ + return ( 4.0/(1.0 + x*x) ); +} + + +int main(int argc,char *argv[]) +{ + + int myrank, size; + + MPI_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &size); + MPI_Comm_rank(MPI_COMM_WORLD, &myrank); + + long long int i, n; + double PI25DT = 3.141592653589793238462643; + double mypi, pi, h, mysum, x; + + + + /* Argument handling from command line */ + if( 2 == argc ){ + n = atoll(argv[1]); + }else{ + if( 0 == myrank ){ + n = 10000000; + printf("Too many or no argument given; using n = %d instead.\n", n); + } + } + + + MPI_Bcast(&n, 1, MPI_LONG_LONG_INT, 0, MPI_COMM_WORLD); + + h = 1.0/( (double)n ); + mysum = 0.0; + + for(i = myrank+1 ; i <= n ; i += size){ + x = h*((double)i - 0.5); + mysum = mysum + f(x); + } + + mypi = h*mysum; + + MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); + + /* Output result if myrank==0 */ + if( 0 == myrank ){ + char* filename = argv[1]; + FILE *fp; + char buf[0x100]; + snprintf(buf, sizeof(buf), "%s", filename); + fp = fopen(buf, "w+"); + fprintf(fp, "\nUsing %d processes and the value n = %d.\n",size,n); + fprintf(fp, "Calculated pi: %.16f, with error %.16f\n\n", pi, fabs(pi - PI25DT)); + fclose(fp); + } + + MPI_Finalize(); + return 0; +} \ No newline at end of file diff --git a/snakemake_executor_plugin_googlebatch/snippets/intel-mpi/run.sh b/snakemake_executor_plugin_googlebatch/snippets/intel-mpi/run.sh index 4e4f943..dbdd9a5 100644 --- a/snakemake_executor_plugin_googlebatch/snippets/intel-mpi/run.sh +++ b/snakemake_executor_plugin_googlebatch/snippets/intel-mpi/run.sh @@ -8,6 +8,6 @@ source /opt/intel/mpi/latest/env/vars.sh if [ $BATCH_TASK_INDEX = 0 ]; then ls which mpirun - echo "{% if resources.mpi %}{{ resources.mpi }}{% else %}mpiexec{% endif %} -hostfile $BATCH_HOSTS_FILE -n {{ settings.tasks }} -ppn {{ settings.tasks_per_node }} {{ command }}" - {% if resources.mpi %}{{ resources.mpi }}{% else %}mpiexec{% endif %} -hostfile $BATCH_HOSTS_FILE -n {{ settings.tasks }} -ppn {{ settings.tasks_per_node }} {{ command }} + echo "{{ command }}" + {{ command }} fi