本帖最后由 Huschein 于 2023-5-13 02:12 编辑
在爆肝一周之后,终于做完了这个工作,特此分享出来!!!文章图片不清晰之处请在文末下载!
1. 前言(纯粹是编译了一个星期之后有感而发,需要干货可以直接转到后面几个部分) “The CMake is complicated while MSVC is messy” 首先的话,文章原文发表在计算化学公社上,故在此特地先感谢公社成员Chris——szk的帮助,没有他我无法独立完成GMX2023_Win的编译工作! 起初想要编译的原因纯粹是因为个人服务器和Linux都已经更新到了GMX2023版本,故有时候文件在Win上处理时,因为只有2020的版本,在某些任务上使用起来因版本不兼容而比较繁琐,遂根据多篇文章作为参考,开始着手于GMX2023_Win的编译工作。 一开始着手编译颇有初生牛犊不怕虎的意味,熟悉了Linux下的编译流程后,以为Win下编译易如反掌,然而事实截然不同。相较于Linux的第一个问题,就是FFTW库的编译,Linux下可以无脑build_own后由系统代肝,但是win不行,不过好在社长Sob老师有相关教程,所以FFTW也没有大费周章。而第二个遇到的问题就是在编译CUDA部分时,遇到cpp标准更换问题,需要手动修改源代码,这里与2022有些许差异,主要出现在optional库和filesystem库,不过在修改之后也获得了解决。第三个问题是我个人PC问题,因为个人PC是1050,所以compute_XX架构比较老,这个修改一下也可以解决。而最让人头疼的问题恰恰是在MD/MT编译线程问题上,这个问题有三种解法,其中有两种可以通过Ninja解决(Chris——szk实现),而我因为一些小问题没有使用Ninja,纯用MSVC解决。 所以在第二部分我会跟大家分析具体的解决方法和一些代码上的个人理解。最后再吐槽一下“The CMake is complicated while MSVC is messy”,MSVC不仅烂在它的内部默认设置上,单核编译更是烂上加烂! 原生编译Github:https://github.com/Hsuchein/Gromacs_For_Windows/releases/tag/publish 2. 具体分析(只想知道如何实现编译直接跳到第四部分) 总体的来说,具体的解决方法在第四部分,这一部分着重讨论报错以及一些底层问题,而不是重在解决问题。 一、NVCC问题: 首先的话,我是完全根据sob老师的帖子进行编译(http://bbs.keinsci.com/thread-11848-1-1.html),在FFTW库上没有什么问题,而后开始建立完build文件准备安装的时候,你会遇到第一个报错 nvcc fatal : Unknown option '-std:c++17' 这个报错看起来应该是NVCC的CPP标准问题,至于如何解决,是依照了Chris——szk的文章(http://bbs.keinsci.com/thread-33986-1-1.html),对于这个的底层逻辑我也不太明白,但是神奇的是,这改完就行了,准确的来说就是把一行代码的“CXX17”改成“CUDA17”即可,改的是gmxManageNvccConfig.cmake这个文件,因为这个文件掌控了gmx的NVCC相关的控制参数,说实话对于能找到这个文件我也是非常钦佩的,换做是我估计直接寄掉了,在不参考他的文章的情况下,无论你如何Google和GPT,愣是找不到一点相关的帖子。在此之后你会遇到第二个报错 nvcc fatal : Unsupported gpu architecture 'compute_89' 这个主要就是因为GPU算力的问题,我具体没有详细的去了解,但是nVidia是有一套标准的,对于我的1050来说,算力就是86,而对于现在性能优异的4090可能就是90的架构,所以关于这个的帖子说多不多,说少不少,也算是比较好解决的,但是一定要注意,必须得要改gmxManageNvccConfig.cmake,因为这是控制文件,他控制了一系列build文件的生成,曾经我很长一段时间去改build文件的compute架构参数,总是反复报错,每次报错后查看build文件内容,发现86又被自动改回了90,当时真的见了鬼了,所以说,了解Cmake的工作机制是多么的重要。随后你会遇到你的第三个报错,准确的来说不是第三个,因为这个类型的错误会一下跳出来一堆错误 error : name followed by "::" must be a class or namespace name [D:\gmxtest\gromacs-2023\build\src\gromacs\libgromacs.vcxproj] 这个错误其实就是CPP标准的问题,在CPP17之前,<filesystem>库和<optional>库是不存在的,相对应的是<experimental/filesystem>、<experimental/optional>两个库,这两个库在CPP17标准之前都是试验库,在17之后才正式的加入CPP标准库文件之中。当时首先尝试了修改cmakelist,企图调整CPP标准为17,但是奇怪的是调了17也确实显示了17,但是每次编译这个库时总是报错说不是17的标准,这我很奇怪,最后在Chris——szk帮助下,他还是通过修改gmxManageNvccConfig.cmake,来加入-std=c++17来调整NVCC的CPP标准解决了这个问题。但是这个问题其实还是挺有意思的,因为我个人多次尝试调整CPP标准不成,于是大胆想了一个念头:既然<experimental/filesystem>存在,不能用CPP17我干脆直接改源代码,实现<experimental/filesystem>的函数,所以我就把各个地方出现该报错的std::filesystem通通改成std::experimental::filesystem,这样就完成了更替,但这才是噩梦的开始。由于CPP17和CPP14的区别,这种方法只能解决这一个函数的问题,随后你会遇到静态断言(static_assert)的参数数目报错,以及虚函数的使用报错,还有各种CPP14不支持CPP17支持的库(tuple)等各种各样的问题,但是这些都是小问题,你在改完之后也都可以运行,原理上只要你一路爆改,全部CPP14,那总是可以的,但问题出现在,某个文件的变量类型问题,具体的已经忘了,总的来说就是因为CPP17支持的一个库,用那个库文件下的一些东西定义了一个变量,然后某个函数参数就是这个类型的变量,然后这个参数去调用你CPP14爆改的变量直接提示你变量类型不匹配,当然我直接想,那就直接去改函数原型,但你会发现,GMX它链接来链接去,你根本找不到函数原型在哪里,毕竟一个.cpp里面它头文件几十个,且这种函数参数变量类型报错还有数十个,那我要寻找并且合理修改的函数原型实在是太多了,并且鬼知道我改了函数原型会不会又出现莫名其妙的报错。所以的话我最终放弃了这个想法,但是Chris——szk后来和我提说,GMX2022用我这个想法是可以的,因为那时还没引入filesystem这个库,不过已经不重要了。
二、MD/MT编译线程问题 Chris——szk和我提使用Ninja来解决这个问题,Ninja的优势不仅在于可以便捷的设置MD/MT线程的使用方式,并且还可以多核并行(MSVC望尘莫及),但是因为个人能力有限,我也尝试过Ninja,最后没成功,遂继续钻研MSVC,如果想要学习Ninja的方法可以查看文章(https://github.com/CondaPereira/Gromacs_windows_Release)。对于MSVC,这涉及到一些MSVC和CMake语法相互交织的问题,我给出的总体评价是:MSVC烂透了!首先如果你尝试打开build出来的GROMACS.Sln,期望通过GUI界面设置MT来编译,我只会告诉你,你想的太天真了,MSVC会毫不犹豫地给你一巴掌,同样我也期望通过修改vcxproj文件来控制MD/MT的问题,我也成功的找到了控制的文件libgromacs.vcxproj,不过MSVC还是会告诉你痴心妄想! 在你每次修改完之后,MSVC总有办法帮你搅回来,最后只能去通过调控cmakelist来解决这个问题,这个其实我看了很多文章,关于cmake语法,在cmake14前后就线程设置问题发生了比较大的变化,具体可以参考微软的文章(https://cmake.org/cmake/help/lat ... html#policy:CMP0091),你要先把policy设置为new来开启新的语法,然后再加入新的句子,所以往上某些解决方法其实是老语法,对于你的cmakelist其实是不生效的,最恶心的地方在于,网上众多帖子给你加句子的地方根!本!不!对!这个非常重要,policy设置在最前面,表示对全局的设置,线程设置在project后,代表对该任务启用不同设置,往上也有的人说MSVC的MT就是无法调控,建议转用Ninja,不过有一说一Ninja确实是可以,但并不代表着MSVC完全不行。总而言之,多试试总是可以的! 三、CLANG与Ninja(optional) 在编译的优化方面当时Ninja会更好,但我不会用,还是那句话,Ninja的问题可以参考Chris——szk的帖子,我之前已经贴出来过了。 关于CLANG的话,毕竟网评它的优化更好,编译出来的性能比MSVC会更好,所以我就采用了CLANG来编译,这个具体的话去查“MSVC调用CLANG编译”相关帖子,具体的来说就是你安装完CLANG,然后在cmakelist的project后添加上CLANG的路径就好了,记得C和CXX都要设置。 3. 性能测试 测试均在个人PC上完成,GTX1050/7th i5,体系是3.3w原子的常规体系,跑常规MD任务。其实其他参数不需要怎么比较了,Win和Linux已经决定了一切;而对于Win的横向比对的话,2023其实在源代码上有了很多优化,但是个人能力所限,看到的主要是很多代码用CPP17覆写,可能在性能和安全性上会更加优秀。不过优化还可以在用MKL库代替FFTW,而CLANG的话根据网评是比MSVC默认编译器要更好的,指令集都已经是AVX2了,也无法再向前了。
命名规则:GMX版本_编译器_GPU架构_系统
GMX2023_CLANG_86_Win CPU使用率 100% GPU使用率 80-95% 每天57ns
GMX2020_MSVC_80_Win CPU使用率100% GPU使用率75%-90% 每天51ns
GMX2023_GCC_86_Linux CPU使用率100% GPU使用率93-100% 每天63ns
测试总结: 1. GMX版本。因为测试的是小体系,所以2023相对于2020没有显示出有事,根据官方的说法,2023在大体系上表现性能会更好,而且体系越大效率比以前越高。并且我们也可以看出来,2023版本的GPU使用效率是更高的,我猜测可能是官方在NVCC上下的功夫(毕竟源代码改翻天了,虽然不能排除compute架构的问题,可能也占一部分原因),而且在2023四月份,gmx官方和nVidia达成了合作,nVidia日后的显卡会在gmx任务中发挥更高效的性能。 2. 操作系统。其实Linux还会更快,之所以Linux一直到57600步才停,完全是因为它完成时间降得太快了,而win降的比较慢。用人话来说,win的天花板是57ns,Linux的地板是64ns,如果继续跑下去,Linux与Win之间的差距只会越来越大。 3. 编译器。三个版本三个编译器,但是我还是要说说,gmx官方是最注重GCC的,同样GCC也是底层优化做的最好的,所以在纯GPU运行的情况下,虽然未做测试,但我仍旧看好Linux,其次则是风评较好的CLANG,最后则是MSVC。
4.快捷步骤 编译准备: MSVC 2022 CLANG(可选择) Ninja(可选择) GROMACS2023包 FFTW包 开始编译 1.做好其他配置NVCC,OMP等 3.解压并建立build目录,进入build目录 4.修改gmxManageNvccConfig.cmake的源代码 把list(APPEND GMX_CUDA_NVCC_FLAGS "${CMAKE_CXX17_STANDARD_COMPILE_OPTION}") 改成 list(APPEND GMX_CUDA_NVCC_FLAGS "${CMAKE_CUDA17_STANDARD_COMPILE_OPTION}") 随后根据你自己的GPU看看需不需要改compute_XX架构,改了就性能会低一些,所以先编译,如果报错就改,具体改多少去nVidia查。 --generate-code=arch=compute_86,code=sm_86 就是把这个数字改成你GPU支持的数字即可。 最后加在gmx_add_nvcc_flag_if_supported(GMX_CUDA_NVCC_FLAGS NVCC_HAS_USE_FAST_MATH -use_fast_math)内加上std=c++17 5.修改Cmakelist文件,这个文件在build文件夹外面 在第一行添上set(CMAKE_POLICY_DEFAULT_CMP0091 NEW) set(CMAKE_POLICY_DEFAULT_CMP NEW) cmake_policy(SET CMP0091 NEW) 然后在project(Gromacs VERSION 2023.0)后添上 if(MSVC) # 设置运行库类型 set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") string(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") endif() 6.cmake建立build文件 cmake .. -DCMAKE_INSTALL_PREFIX=D:/gmxtest/gromacs-2023 -DGMX_FFT_LIBRARY=fftw3 -DCMAKE_PREFIX_PATH=D:/gmxtest/fftw-3.3.10 -G "Visual Studio 17 2022" -DGMX_GPU=CUDA -DCUDA_TOOLKIT_ROOT_DIR=E:/GPU2/bin 7. cmake 安装 cmake --build . --target INSTALL --config Release 如果严格按照此步骤,基本上不太可能遇到bug,如果遇到bug请先检查是否在路径设置和其他方面出现问题,因为这一套修改基本从底层上解决了GMX2023对Win所有不适应的地方,毕竟笔者老爷机(2018拯救者)都可以成功编译。专业术语用错地方请指正,写作测试不易!
|