slurm-wrapper.sh 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #!/bin/bash
  2. #
  3. # Use this script if you cannot use MPI but you have a
  4. # NFS available (or some other means of communicating
  5. # the ip/port between computers).
  6. #
  7. # Don't reuse the same "FILE_WITH_LOC" since the race
  8. # conditions are ugly, and the files won't be
  9. # automatically deleted after this script.
  10. #
  11. OUTPUT_FILE_DIR="$1"
  12. FILE_WITH_LOC="$2"
  13. CUDADL_PATH="$3"
  14. #
  15. if [ "$SLURM_LOCALID" == "0" ] ; then
  16. if [ "$SLURM_PROCID" == "0" ] ; then
  17. # adapted from https://superuser.com/questions/184307/bash-create-anonymous-fifo
  18. # and https://stackoverflow.com/questions/8297415/in-bash-how-to-find-the-lowest-numbered-unused-file-descriptor
  19. #
  20. PIPE=$(mktemp -u)
  21. # create a named pipe
  22. mkfifo $PIPE
  23. # need to get a bi-directional file descriptor first to prevent bash from blocking
  24. exec {FD}<>$PIPE
  25. exec {FD1}>$PIPE
  26. exec {FD2}<$PIPE
  27. # unlink the named pipe
  28. rm $PIPE
  29. # don't need this file descriptor anymore
  30. exec {FD}>&-
  31. #
  32. CONTROLLER_BOUNDCB_FD=$FD1 ${CUDADL_PATH}/controller "${@:4}" &
  33. CONTROLLER_PID=$!
  34. trap "kill $CONTROLLER_PID ; exit" SIGINT
  35. # the controller should close its write file descriptor, so we need to close ours
  36. exec {FD1}>&-
  37. #
  38. BYTE1=$(head -c 1 <&$FD2)
  39. BYTE2=$(head -c 1 <&$FD2)
  40. BYTE1=$(LC_CTYPE=C printf '%d' "'$BYTE1")
  41. BYTE2=$(LC_CTYPE=C printf '%d' "'$BYTE2")
  42. PORT=$((BYTE2*256+BYTE1))
  43. # is there no better way in bash?!
  44. #
  45. read IP <&$FD2
  46. #
  47. exec {FD2}<&-
  48. #
  49. sleep 10
  50. # give the controller time to get ready
  51. # not sure if needed, but hopefully it fixes a bug with workers disconnecting
  52. #
  53. echo "$IP $PORT" > $FILE_WITH_LOC
  54. #
  55. fi
  56. #
  57. COUNTER=0
  58. START_DPNODE=1
  59. while [ ! -f $FILE_WITH_LOC ] ; do
  60. if [ $COUNTER -gt 60 ] ; then
  61. # file still doesn't exist after 60 seconds
  62. START_DPNODE=0
  63. break
  64. fi
  65. sleep 1
  66. COUNTER=$((COUNTER+1))
  67. done
  68. #
  69. if [ $START_DPNODE -eq 1 ] ; then
  70. sleep 1 # to make sure it is done writing
  71. read IP PORT < $FILE_WITH_LOC
  72. #
  73. OUTPUT_FILE="${OUTPUT_FILE_DIR}/dpnode_${SLURM_NODEID}_${SLURM_LOCALID}.out"
  74. TMP_OUTPUT_FILE="${SLURM_TMPDIR}/dpnode_${SLURM_NODEID}_${SLURM_LOCALID}.out"
  75. ${CUDADL_PATH}/dpnode $IP $PORT > "${TMP_OUTPUT_FILE}" 2>&1
  76. mv "$TMP_OUTPUT_FILE" "$OUTPUT_FILE"
  77. fi
  78. #
  79. if [ ! -z "$CONTROLLER_PID" ] ; then
  80. wait "$CONTROLLER_PID"
  81. fi
  82. else
  83. COUNTER=0
  84. START_WORKER=1
  85. while [ ! -f $FILE_WITH_LOC ] ; do
  86. if [ $COUNTER -gt 60 ] ; then
  87. # file still doesn't exist after 60 seconds
  88. START_WORKER=0
  89. break
  90. fi
  91. sleep 1
  92. COUNTER=$((COUNTER+1))
  93. done
  94. #
  95. if [ $START_WORKER -eq 1 ] ; then
  96. sleep 1 # to make sure it is done writing
  97. read IP PORT < $FILE_WITH_LOC
  98. #
  99. WORKER_ID=$((SLURM_LOCALID-1))
  100. #
  101. OUTPUT_FILE="${OUTPUT_FILE_DIR}/worker_${SLURM_NODEID}_${WORKER_ID}.out"
  102. TMP_OUTPUT_FILE="${SLURM_TMPDIR}/worker_${SLURM_NODEID}_${WORKER_ID}.out"
  103. ${CUDADL_PATH}/worker $IP $PORT $WORKER_ID > "${TMP_OUTPUT_FILE}" 2>&1
  104. mv "$TMP_OUTPUT_FILE" "$OUTPUT_FILE"
  105. fi
  106. fi