Link: https://sskaje.me/2015/07/macbook-pro-%e7%bc%96%e8%af%91%e6%94%af%e6%8c%81cuda%e7%9a%84msieve/
之前试过在CentOS 6上编译GMP-ECM和MSIEVE,后来有一天发现本机的MacPorts带的GMP-ECM不是最新版,当前6.4.4的情况下,MacPorts里的才6.3.
顺道也想侥幸一下看看这个2012款的rmbp能不能上CUDA,于是开始折腾。
环境
MacBook Pro with Retina Display 2012 (GT 650 M)
OS X 10.10.4
MacPorts
安装CUDA环境
CUDA Toolkit官方下载地址是:https://developer.nvidia.com/cuda-downloads
下载里目前最新版本是7.0.29,但是下载完成之后设置里还会提示有新版。
另外,Nvidia官方还给了个NVIDIA CUDA Getting Started Guide for Mac OS X.
我就简单地装了这个toolkit 没配环境变了。
第一次尝试
最早的尝试基于MacPorts自带的gmp和gmp-ecm编译CUDA版本的msieve,顺道还编译了个CPU版本的
1 2 3 4 5 6 |
# 安装 gmp 和 gmp-ecm $ port install gmp gmp-ecm # 编译 msieve,开gpu PATH=/usr/local/cuda/bin/:$PATH MACHINE_FLAGS="-I/opt/local/include -I/usr/local/cuda/include" LIBS="-L/opt/local/lib -L/usr/local/cuda/lib" make all ECM=1 CUDA=1 # 编译 msieve 无gpu版本 MACHINE_FLAGS="-I/opt/local/include" LIBS="-L/opt/local/lib" make all ECM=1 |
这俩拿 RSA-39 的跑,都正常。但是自己生成了个RSA-256的,就有个ECM里报出的assert,没法工作。于是尝试编译ecm。
中间试过好几种方案,最后记录最后的版本
最新版 GMP, GMP-ECM, MSIEVE
最新版 GMP-ECM 也自带GPU的计算了,于是我也就把这个加了进去。
首先,从项目源上拉下最新版本
1 2 3 |
$ svn co svn://scm.gforge.inria.fr/svnroot/ecm/trunk ecm-trunk $ svn co svn://svn.code.sf.net/p/msieve/code/trunk msieve-trunk $ hg clone https://gmplib.org/repo/gmp/ gmp-master |
编译 GMP,原本是拉的最新release,但是中间遇到了一些问题,asm的编译不过去,于是也用trunk了。
1 2 3 4 5 6 7 8 9 10 11 |
cd gmp-master sh .bootstrap ./configure \ --prefix=/Users/sskaje/Work/ecm \ --enable-fft \ --enable-cxx \ --enable-fat \ --enable-assembly make make check make install |
编译 ECM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
cd ../ecm autoreconf -i PATH=/usr/local/cuda/bin:$PATH ./configure --prefix=/Users/sskaje/Work/ecm \ --with-gmp=/Users/sskaje/Work/ecm \ --disable-asm-redc \ --enable-aprcl \ --enable-sse2 \ --enable-openmp \ --enable-mulredc-svoboda \ --enable-gpu=sm_30 \ --with-cuda make |
第一次configure的时候报当前系统不支持cuda,发现了个bug,报了官方,然后继续了,又发现这个错误:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
/bin/sh ./libtool --tag=CC --mode=link gcc -g -W -Wall -Wundef -O2 -pedantic -fomit-frame-pointer -m64 -o ecm ecm-auxi.o ecm-b1_ainc.o ecm-candi.o ecm-eval.o ecm-random.o ecm-main.o ecm-resume.o ecm-getprime.o aprtcle/ecm-mpz_aprcl.o ecm-memusage.o libecm.la /Users/sskaje/Work/ecm/lib/libgmp.a -lm -lm -lm -lm -lm libtool: link: gcc -g -W -Wall -Wundef -O2 -pedantic -fomit-frame-pointer -m64 -o ecm ecm-auxi.o ecm-b1_ainc.o ecm-candi.o ecm-eval.o ecm-random.o ecm-main.o ecm-resume.o ecm-getprime.o aprtcle/ecm-mpz_aprcl.o ecm-memusage.o ./.libs/libecm.a /Users/sskaje/Work/ecm/lib/libgmp.a -lm ld: warning: ignoring file ./.libs/libecm.a, file was built for archive which is not the architecture being linked (x86_64): ./.libs/libecm.a Undefined symbols for architecture x86_64: "___ecm_cputime", referenced from: _main in ecm-main.o "___ecm_get_random_ul", referenced from: _main in ecm-main.o "___ecm_pm1_random_seed", referenced from: _main in ecm-main.o "___ecm_pp1_random_seed", referenced from: _main in ecm-main.o "_build_curves_with_torsion2", referenced from: _main in ecm-main.o "_ecm_clear", referenced from: _main in ecm-main.o "_ecm_factor", referenced from: _main in ecm-main.o "_ecm_init", referenced from: _main in ecm-main.o "_ecm_version", referenced from: _main in ecm-main.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) make[2]: *** [ecm] Error 1 make[1]: *** [all-recursive] Error 1 make: *** [all] Error 2 |
用 ar -tv .libs/libecm.a,发现包里还有个libgmp.a,ar -d干掉就好了
1 2 |
$ ar -d .libs/libecm.a libgmp.a $ make |
但是运行的时候
1 2 3 4 5 |
$ ./ecm dyld: Library not loaded: @rpath/libcudart.7.0.dylib Referenced from: /Users/sskaje/Work/msieve/ecm-trunk/./ecm Reason: image not found Trace/BPT trap: 5 |
看到@rpath,研究了半天,确信是跟 linux ldconfig 类似的问题,但是搜到的基本都是XCode如何修改。。。
最后发现是之前文档里提示加环境变量的问题:
1 2 3 |
$ export DYLD_LIBRARY_PATH=/usr/local/cuda/lib:$DYLD_LIBRARY_PATH $ ./ecm Invalid arguments. See ./ecm --help. |
编译MSIEVE
这个更麻烦,主要原因是7.x的CUDA不支持sm_1x,而MSIEVE里试图编译了 sm_11, sm_13, sm_20 三个架构。
1 2 |
$ cd ../msieve-trunk $ PATH=/usr/local/cuda/bin/:$PATH MACHINE_FLAGS=" -I/Users/sskaje/Work/ecm/include -I/usr/local/cuda/include" LIBS="-L/Users/sskaje/Work/ecm/lib -L/usr/local/cuda/lib" make all ECM=1 CUDA=1 |
错误如下
1 2 3 |
"/usr/local/cuda/bin//nvcc" -arch sm_11 -ptx -o stage1_core_sm11.ptx gnfs/poly/stage1/stage1_core_gpu/stage1_core.cu nvcc fatal : Value 'sm_11' is not defined for option 'gpu-architecture' make: *** [stage1_core_sm11.ptx] Error 1 |
因为GT 650M 最高支持3.0的架构,于是我去改了下代码,包括:
1 2 3 |
Makefile b40c/Makefile gnfs/poly/stage1/stage1_sieve_gpu.c |
至少,需要修改前两个Makefile,把sm_11和sm_13的编译选项删掉
运行
GPU版本的msieve运行需要b40c/sort_engine_smXX.so,所以如果要移动目录,需要保证这个.so的相对位置。
1 2 3 |
$ ./msieve-gpu -g 0 -n deadline: 800 CPU-seconds per coefficient error (line 1135): CUDA_ERROR_OUT_OF_MEMORY |
切回来,花屏。
换个
1 2 |
$ ./msieve-gpu -g 1 -n error: GPU 1 does not exist or is not CUDA-enabled |
而,MSIEVE的GPU计算部分只在NFS polynomial selection里有用,其他过程没区别,于是白瞎了。