makemake.sh 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #!/bin/bash
  2. # EWM: This is a makefile-only cutdown of Teal Dulcet's much more extensive Mlucas install/build/tune
  3. # script, available at https://raw.github.com/tdulcet/Distributed-Computing-Scripts/master/mlucas.sh ;
  4. # he does not explicitly use the GPL boilerplate as below, but assures me his version is GPL-covered.
  5. ################################################################################
  6. # #
  7. # (C) 2021 by Ernst W. Mayer. #
  8. # #
  9. # This program is free software; you can redistribute it and/or modify it #
  10. # under the terms of the GNU General Public License as published by the #
  11. # Free Software Foundation; either version 2 of the License, or (at your #
  12. # option) any later version. #
  13. # #
  14. # This program is distributed in the hope that it will be useful, but WITHOUT #
  15. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
  16. # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
  17. # more details. #
  18. # #
  19. # You should have received a copy of the GNU General Public License along #
  20. # with this program; see the file GPL.txt. If not, you may view one at #
  21. # http://www.fsf.org/licenses/licenses.html, or obtain one by writing to the #
  22. # Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #
  23. # 02111-1307, USA. #
  24. # #
  25. ################################################################################
  26. # Exit if any of the sommands fail:
  27. set -e
  28. # for mode in avx512 avx2 avx sse2; do
  29. # if grep -iq "$mode" /proc/cpuinfo; then
  30. # echo -e "The CPU supports the ${mode^^} SIMD build mode.\n"
  31. # ARGS+=( "-DUSE_${mode^^}" )
  32. # break
  33. # fi
  34. # done
  35. # $0 contains script-name, but $@ starts with first ensuing cmd-line arg, if it exists:
  36. echo "Total number of arguments : $#"
  37. for ((i=1; i<=$#; ++i)); do
  38. echo "Arg[$i] = ${!i}"
  39. done
  40. if [[ $# -gt 1 ]]; then
  41. echo "Usage: $0 [SIMD build mode]" >&2
  42. echo "Only 1 optional argument supported, it must be one of the supported SIMD-arithmetic types:" >&2
  43. echo -e "\t[x86_64: avx512_skylake avx512_knl avx2 avx sse2]; [Armv8: asimd]; or 'nosimd' for scalar-double build.\n" >&2
  44. exit 1
  45. fi
  46. DIR=obj
  47. EXE=Mlucas
  48. ARGS=()
  49. if echo "$OSTYPE" | grep -iq 'darwin'; then
  50. echo -e "MacOS detected for build host.\n"
  51. CPU_THREADS=$(sysctl -n hw.ncpu)
  52. else # echo "$OSTYPE" | grep -iq 'linux'
  53. echo -e "Assuming OS = Linux for build host.\n"
  54. CPU_THREADS=$(nproc --all)
  55. fi
  56. # Thx to tdulcet for streamlined case-based syntax here, but ugh - non-matching ')', really?:
  57. if [[ $# -eq 1 ]]; then
  58. if [ "$1" = 'avx512_skylake' ]; then
  59. echo "Building for avx512_skylake SIMD in directory obj_$1; the executable will be named Mlucas_$1"
  60. ARGS+=( "-DUSE_AVX512" -march=skylake-avx512 )
  61. elif [ "$1" = 'avx512_knl' ]; then
  62. echo "Building for avx2 SIMD in directory obj_$1; the executable will be named Mlucas_$1"
  63. ARGS+=( "-DUSE_AVX512" -march=knl )
  64. elif [ "$1" = 'avx2' ]; then
  65. echo "Building for avx2 SIMD in directory obj_$1; the executable will be named Mlucas_$1"
  66. ARGS+=( "-DUSE_AVX2" -mavx2 )
  67. elif [ "$1" = 'avx' ]; then
  68. echo "Building for avx SIMD in directory obj_$1; the executable will be named Mlucas_$1"
  69. ARGS+=( "-DUSE_AVX" -mavx )
  70. elif [ "$1" = 'sse2' ]; then
  71. echo "Building for sse2 SIMD in directory obj_$1; the executable will be named Mlucas_$1"
  72. ARGS+=( "-DUSE_SSE2" )
  73. elif [ "$1" = 'asimd' ]; then
  74. echo "Building for avx2 SIMD in directory obj_$1; the executable will be named Mlucas_$1"
  75. ARGS+=( "-DUSE_ARM_V8_SIMD" )
  76. elif [ "$1" = 'nosimd' ]; then
  77. echo "Building in scalar-double (no-SIMD) mode in directory obj_$1; the executable will be named Mlucas_$1"
  78. # This one's a no-op
  79. else
  80. echo "Unrecognized SIMD-build flag ... aborting."
  81. exit 1
  82. fi
  83. DIR+="_$1"
  84. EXE+="_$1"
  85. elif uname -a | grep -iq 'Mac'; then
  86. echo -e "MacOS detected.\n"
  87. if sysctl -a | grep machdep.cpu.features | grep -iq 'avx512'; then
  88. echo -e "The CPU supports the AVX512 SIMD build mode.\n"
  89. ARGS+=( "-DUSE_AVX512" -march=native )
  90. elif sysctl -a | grep machdep.cpu.features | grep -iq 'avx2'; then
  91. echo -e "The CPU supports the AVX2 SIMD build mode.\n"
  92. ARGS+=( "-DUSE_AVX2" -march=native -mavx2 )
  93. elif sysctl -a | grep machdep.cpu.features | grep -iq 'avx'; then
  94. echo -e "The CPU supports the AVX SIMD build mode.\n"
  95. ARGS+=( "-DUSE_AVX" -march=native -mavx )
  96. elif sysctl -a | grep machdep.cpu.features | grep -iq 'sse2'; then
  97. echo -e "The CPU supports the SSE2 SIMD build mode.\n"
  98. ARGS+=( "-DUSE_SSE2" -march=native )
  99. elif sysctl -a | grep machdep.cpu.features | grep -iq 'asimd'; then
  100. echo -e "The CPU supports the ASIMD build mode.\n"
  101. ARGS+=( "-DUSE_ARM_V8_SIMD" -march=native )
  102. else
  103. echo -e "The CPU supports no Mlucas-recognized ASIMD build mode ... building in scalar-double mode.\n"
  104. ARGS+=( -march=native )
  105. fi
  106. else
  107. echo -e "Assuming OS = Linux.\n"
  108. if grep -iq 'avx512' /proc/cpuinfo; then
  109. echo -e "The CPU supports the AVX512 SIMD build mode.\n"
  110. ARGS+=( "-DUSE_AVX512" -march=native )
  111. elif grep -iq 'avx2' /proc/cpuinfo; then
  112. echo -e "The CPU supports the AVX2 SIMD build mode.\n"
  113. ARGS+=( "-DUSE_AVX2" -march=native -mavx2 )
  114. elif grep -iq 'avx' /proc/cpuinfo; then
  115. echo -e "The CPU supports the AVX SIMD build mode.\n"
  116. ARGS+=( "-DUSE_AVX" -march=native -mavx )
  117. elif grep -iq 'sse2' /proc/cpuinfo; then
  118. echo -e "The CPU supports the SSE2 SIMD build mode.\n"
  119. ARGS+=( "-DUSE_SSE2" -march=native )
  120. elif grep -iq 'asimd' /proc/cpuinfo; then
  121. echo -e "The CPU supports the ASIMD build mode.\n"
  122. ARGS+=( "-DUSE_ARM_V8_SIMD" -march=native )
  123. else
  124. echo -e "The CPU supports no Mlucas-recognized ASIMD build mode ... building in scalar-double mode.\n"
  125. ARGS+=( -march=native )
  126. fi
  127. fi
  128. # -p prevents "File exists" warning if obj-dir already exists:
  129. mkdir -p "$DIR"
  130. cd "$DIR"
  131. # Clang-under-MacOS linker barfs if one tries to explicitly invoke standard libs - h/t tdulcet for the
  132. # conditional-inline syntax. Some OSes put the GMP headers in /usr/local/include, so -I that path in the
  133. # compile command. If said path does not exist, make silently ignores it.
  134. # Re. the -g flag to include the debugging symbols, they bloat executable size but if someone's Mlucas
  135. # crashes/segfaults, one can rerun with GDB (gdb -ex=r ./Mlucas) to see the filename, line number and
  136. # stack trace of the issue. If one wishes, one can run 'strip -g Mlucas' to remove the debugging symbols:
  137. cat << EOF > Makefile
  138. CC?=gcc
  139. OBJS=\$(patsubst ../src/%.c, %.o, \$(wildcard ../src/*.c))
  140. $EXE: \$(OBJS)
  141. \$(CC) -Wall -g -o \$@ \$(OBJS) $(echo "$OSTYPE" | grep -iq 'darwin' || echo "-lm -lpthread -lrt") -lgmp
  142. %.o: ../src/%.c
  143. \$(CC) -Wall -g -c -I/usr/local/include -O3 ${ARGS[@]} -DUSE_THREADS \$<
  144. clean:
  145. rm -f *.o
  146. EOF
  147. echo -e "\nBuilding Mlucas"
  148. printf "%s CPU cores detected ... parallel-building using that number of make threads.\n" "$CPU_THREADS"
  149. if ! make -j "$CPU_THREADS" > build.log 2>&1; then
  150. echo -e "There were build errors - see build.log for details.\n"
  151. exit 1
  152. fi