diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..7cbe275046a42350e05301fa3e51caa9dcc81710 Binary files /dev/null and b/.DS_Store differ diff --git a/container/openeuler-bisheng2-bowtie2-2.4.5.def b/container/openeuler-bisheng2-bowtie2-2.4.5.def new file mode 100644 index 0000000000000000000000000000000000000000..878517802ab3e4a4fe396e26c254aad9bf14aabb --- /dev/null +++ b/container/openeuler-bisheng2-bowtie2-2.4.5.def @@ -0,0 +1,35 @@ +BootStrap: docker +From: openeuler/openeuler + +%environment + source /etc/profile || true + source /etc/profile.d/modules.sh + cd /hpcrunner + source env.sh + +%post + # Install the necessary development environment + yum install -y environment-modules git wget unzip make flex tar + # Install base gcc + yum install -y gcc gcc-c++ make cmake automake zlib-devel bzip2-devel xz-devel curl-devel openssl-devel + source /etc/profile || true + git config --global http.sslVerify false + git clone https://gitee.com/openeuler/hpcrunner.git + cd hpcrunner + source ./init.sh + ./jarvis -i + # Switch config + ./jarvis -use templates/bowtie2/2.4.5/data.bowtie2.arm.cpu.config + # downloads bowtie2 + ./jarvis -d + # install dependency + ./jarvis -dp + # build bowtie2 + ./jarvis -b + # run bowtie2 + ./jarvis -r + # clean downloads directory + rm -rf downloads + +%labels + Author Zu \ No newline at end of file diff --git a/container/openeuler-gcc-9.3.0-bowtie2-2.4.5.def b/container/openeuler-gcc-9.3.0-bowtie2-2.4.5.def new file mode 100644 index 0000000000000000000000000000000000000000..0c6b191d3be19c7a8d29f8efeb6be647e1ec1170 --- /dev/null +++ b/container/openeuler-gcc-9.3.0-bowtie2-2.4.5.def @@ -0,0 +1,35 @@ +BootStrap: docker +From: openeuler/openeuler + +%environment + source /etc/profile || true + source /etc/profile.d/modules.sh + cd /hpcrunner + source env.sh + +%post + # Install the necessary development environment + yum install -y environment-modules git flex wget vim tar unzip coreutils + # Install base gcc + yum install -y gcc gcc-c++ make cmake libgfortran automake zlib-devel bzip2-devel xz-devel curl-devel openssl-devel + source /etc/profile || true + git config --global http.sslVerify false + git clone https://gitee.com/openeuler/hpcrunner.git + cd hpcrunner + source ./init.sh + ./jarvis -i + # Switch config + ./jarvis -use templates/bowtie2/2.4.5/data.bowtie2.x86.cpu.config + # downloads bowtie2 + ./jarvis -d + # install dependency + ./jarvis -dp + # build bowtie2 + ./jarvis -b + # run bowtie2 + ./jarvis -r + # clean downloads directory + rm -rf downloads + +%labels + Author Zu \ No newline at end of file diff --git a/doc/.DS_Store b/doc/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..0a673fc19d02e8e38c917f7e3cf7962a222c8e03 Binary files /dev/null and b/doc/.DS_Store differ diff --git "a/doc/bowtie2/\343\200\212\345\237\272\344\272\216openEuler\347\232\204bowtie2\350\275\257\344\273\266\346\265\213\350\257\225\346\212\245\345\221\212\343\200\213.md" "b/doc/bowtie2/\343\200\212\345\237\272\344\272\216openEuler\347\232\204bowtie2\350\275\257\344\273\266\346\265\213\350\257\225\346\212\245\345\221\212\343\200\213.md" new file mode 100644 index 0000000000000000000000000000000000000000..84b97a3ba3ee7bb4aa66cc60361f564825222fb9 --- /dev/null +++ "b/doc/bowtie2/\343\200\212\345\237\272\344\272\216openEuler\347\232\204bowtie2\350\275\257\344\273\266\346\265\213\350\257\225\346\212\245\345\221\212\343\200\213.md" @@ -0,0 +1,684 @@ +# 《基于openEuler的Bowtie2软件测试报告》 + +## 1.规范性自检 + +项目使用了Artistic Style对文件进行格式化 + +AStyle,即Artistic Style,是一个可用于C, C++, C++/CLI, Objective‑C, C# 和Java编程语言格式化和美化的工具。我们在使用编辑器的缩进(TAB)功能时,由于不同编辑器的差别,有的插入的是制表符,有的是2个空格,有的是4个空格。这样如果别人用另一个编辑器来阅读程序时,可能会由于缩进的不同,导致阅读效果一团糟。为了解决这个问题,使用C++开发了一个插件,它可以自动重新缩进,并手动指定空格的数量,自动格式化源文件。它是可以通过命令行使用,也可以作为插件,在其他IDE中使用。 + +文件格式化配置参考文件`config/bowtie2.astylerc`,文件内容如下 + +```astylerc +# Bowtie2 formatting options for Artistic Style +--style=allman +--indent=spaces=3 +--keep-one-line-statements +--keep-one-line-blocks +--pad-header +--max-code-length=80 +--max-instatement-indent=80 +--min-conditional-indent=0 +--indent-col1-comments +--indent-labels +--break-after-logical +--add-brackets +--indent-switches +--convert-tabs +--lineend=linux +--suffix=none +--preserve-date +--formatted +``` + +对于当前项目,检查代码规范性,可以通过使用AStyle对所有源码进行重新格式化,然后使用git查看文件修改。 + +统计代码不规范内容。 + +## 1.1.选择统计文件类型 + +统计项目文件类型及其文件数量 + +使用python编写脚本文件 + +```python +# -*- coding: utf-8 -*- + +import os + +print (os.getcwd()) + +def getAllFiles(targetDir): + files = [] + listFiles = os.listdir(targetDir) + for i in range(0, len(listFiles)): + path = os.path.join(targetDir, listFiles[i]) + if os.path.isdir(path): + files.extend(getAllFiles(path)) + elif os.path.isfile(path): + files.append(path) + return files + +all_files=getAllFiles(os.curdir) +type_dict=dict() + +for each_file in all_files: + if os.path.isdir(each_file): + type_dict.setdefault("文件夹",0) + type_dict["文件夹"]+=1 + else: + ext=os.path.splitext(each_file)[1] + type_dict.setdefault(ext,0) + type_dict[ext]+=1 + +for each_type in type_dict.keys(): + print ("当前文件夹下共有【%s】的文件%d个" %(each_type,type_dict[each_type])) +``` + + +在bowtie2项目根目录下运行,运行结果如下 + +```bash +[root@ecs-7567 bowtie2]# python main.py +/root/bowtie2 +当前文件夹下共有【】的文件25个 +当前文件夹下共有【.pl】的文件8个 +当前文件夹下共有【.md】的文件2个 +当前文件夹下共有【.py】的文件10个 +当前文件夹下共有【.cpp】的文件58个 +当前文件夹下共有【.idx】的文件1个 +当前文件夹下共有【.bam】的文件1个 +当前文件夹下共有【.fa】的文件3个 +当前文件夹下共有【.sample】的文件11个 +当前文件夹下共有【.gif】的文件1个 +当前文件夹下共有【.yml】的文件2个 +当前文件夹下共有【.fq】的文件3个 +当前文件夹下共有【.sh】的文件22个 +当前文件夹下共有【.pack】的文件1个 +当前文件夹下共有【.bench】的文件1个 +当前文件夹下共有【.pm】的文件9个 +当前文件夹下共有【.markdown】的文件1个 +当前文件夹下共有【.bt2】的文件6个 +当前文件夹下共有【.h】的文件75个 +当前文件夹下共有【.png】的文件3个 +当前文件夹下共有【.shtml】的文件5个 +当前文件夹下共有【.ssi】的文件7个 +当前文件夹下共有【.json】的文件2个 +当前文件夹下共有【.css】的文件1个 +当前文件夹下共有【.txt】的文件2个 +当前文件夹下共有【.html】的文件2个 +当前文件夹下共有【.html】的文件2个 +``` + +查看上述结果可知主要源码文件后缀名为 `cpp`,`h`. + +## 1.2.统计源码总行数 + +统计所有源码文件的代码行数 + +```bash + find ./ -regex ".*\.h\|.*\.cpp" | xargs wc -l +``` + +统计结果 + +```bash + 84788 total +``` + +## 1.3.统计不符合要求的总行数 + +对文件后缀名为 `cpp`,`hpp`,`h`,`c`, 的所有文件进行格式 + +```bash +[root@ecs-7567 bowtie2]# astyle --project=config/bowtie2.astylerc -R ./*.cpp,*.h -v +Artistic Style 3.1 09/25/2022 +Project option file /root/bowtie2/config/bowtie2.astylerc +------------------------------------------------------------ +Directory ./*.cpp,*.h +------------------------------------------------------------ +Formatted aligner_bt.cpp +Formatted aligner_bt.h +Formatted aligner_cache.cpp +Formatted aligner_cache.h +Formatted aligner_driver.cpp +Formatted aligner_driver.h +Formatted aligner_metrics.h +Formatted aligner_report.h +Formatted aligner_result.cpp +Formatted aligner_result.h +Formatted aligner_seed.cpp +Formatted aligner_seed.h +Formatted aligner_seed2.cpp +Formatted aligner_seed2.h +Formatted aligner_seed_policy.cpp +Formatted aligner_seed_policy.h +Formatted aligner_sw.cpp +Formatted aligner_sw.h +Formatted aligner_sw_common.h +Formatted aligner_sw_driver.cpp +Formatted aligner_sw_driver.h +Formatted aligner_sw_nuc.h +Formatted aligner_swsse.cpp +Formatted aligner_swsse.h +Formatted aligner_swsse_ee_i16.cpp +Formatted aligner_swsse_ee_u8.cpp +Formatted aligner_swsse_loc_i16.cpp +Formatted aligner_swsse_loc_u8.cpp +Formatted aln_sink.cpp +Formatted aln_sink.h +Formatted alphabet.cpp +Formatted alphabet.h +Formatted assert_helpers.h +Formatted banded.cpp +Formatted banded.h +Formatted binary_sa_search.h +Formatted bitpack.h +Formatted blockwise_sa.h +Formatted bowtie_build_main.cpp +Formatted bowtie_main.cpp +Formatted bt2_build.cpp +Formatted bt2_dp.cpp +Formatted bt2_idx.cpp +Formatted bt2_idx.h +Formatted bt2_inspect.cpp +Formatted bt2_io.cpp +Formatted bt2_locks.cpp +Formatted bt2_locks.h +Formatted bt2_search.cpp +Formatted bt2_search.h +Formatted bt2_util.cpp +Formatted btypes.h +Formatted ccnt_lut.cpp +Formatted cpu_numa_info.cpp +Formatted diff_sample.cpp +Formatted diff_sample.h +Formatted dp_framer.cpp +Formatted dp_framer.h +Formatted ds.cpp +Formatted ds.h +Formatted edit.cpp +Formatted edit.h +Formatted endian_swap.h +Formatted fast_mutex.h +Formatted filebuf.h +Formatted formats.h +Formatted group_walk.h +Formatted ival_list.cpp +Formatted ival_list.h +Formatted ls.cpp +Formatted ls.h +Formatted mask.cpp +Formatted mask.h +Formatted multikey_qsort.h +Formatted opts.h +Formatted outq.cpp +Formatted outq.h +Formatted pat.cpp +Formatted pat.h +Formatted pe.cpp +Formatted pe.h +Formatted presets.cpp +Formatted presets.h +Formatted processor_support.h +Formatted qual.cpp +Formatted qual.h +Formatted random_source.cpp +Formatted random_source.h +Formatted random_util.h +Formatted read.h +Formatted read_qseq.cpp +Formatted ref_coord.cpp +Formatted ref_coord.h +Formatted ref_read.cpp +Formatted ref_read.h +Formatted reference.cpp +Formatted reference.h +Formatted sam.cpp +Formatted sam.h +Formatted scoring.cpp +Formatted scoring.h +Formatted sequence_io.h +Formatted shmem.cpp +Formatted shmem.h +Formatted simple_func.cpp +Formatted simple_func.h +Formatted sse_util.cpp +Formatted sse_util.h +Formatted sstring.cpp +Formatted sstring.h +Formatted str_util.h +Formatted threading.h +Formatted threadpool.h +Formatted timer.h +Formatted tokenize.h +Formatted unique.cpp +Formatted unique.h +Formatted util.h +Formatted word_io.h +Formatted zbox.h +Formatted zstd_decompress.cpp +Formatted zstd_decompress.h +Formatted third_party/cpuid.h +------------------------------------------------------------ + 123 formatted 10 unchanged 0.46 seconds 94,241 lines +``` + +使用git 对文件格式化修改内容进行统计 + +``` +[root@ecs-7567 bowtie2]# git commit -m "fomat update" +[master 1a8f07f] fomat update + 125 files changed, 92211 insertions(+), 82842 deletions(-) + rewrite aligner_bt.cpp (92%) + rewrite aligner_bt.h (70%) + rewrite aligner_cache.cpp (77%) + rewrite aligner_cache.h (81%) + rewrite aligner_driver.cpp (89%) + rewrite aligner_metrics.h (88%) + rewrite aligner_result.cpp (88%) + rewrite aligner_result.h (89%) + rewrite aligner_seed.cpp (89%) + rewrite aligner_seed.h (90%) + rewrite aligner_seed2.cpp (93%) + rewrite aligner_seed2.h (82%) + rewrite aligner_seed_policy.cpp (74%) + rewrite aligner_seed_policy.h (83%) + rewrite aligner_sw.cpp (93%) + rewrite aligner_sw.h (71%) + rewrite aligner_sw_common.h (80%) + rewrite aligner_sw_driver.cpp (89%) + rewrite aligner_sw_driver.h (78%) + rewrite aligner_sw_nuc.h (75%) + rewrite aligner_swsse.h (78%) + rewrite aligner_swsse_ee_i16.cpp (87%) + rewrite aligner_swsse_ee_u8.cpp (87%) + rewrite aligner_swsse_loc_i16.cpp (87%) + rewrite aligner_swsse_loc_u8.cpp (86%) + rewrite aln_sink.cpp (88%) + rewrite aln_sink.h (82%) + rewrite alphabet.cpp (77%) + rewrite assert_helpers.h (65%) + rewrite blockwise_sa.h (88%) + rewrite bt2_build.cpp (87%) + rewrite bt2_dp.cpp (84%) + rewrite bt2_idx.cpp (67%) + rewrite bt2_idx.h (90%) + rewrite bt2_inspect.cpp (82%) + rewrite bt2_io.cpp (88%) + rewrite bt2_locks.cpp (95%) + rewrite bt2_locks.h (76%) + rewrite bt2_search.cpp (89%) + rewrite bt2_util.cpp (72%) + rewrite ccnt_lut.cpp (94%) + create mode 100644 config/bowtie2.astylerc + rewrite diff_sample.h (82%) + rewrite dp_framer.cpp (75%) + rewrite dp_framer.h (74%) + rewrite ds.cpp (68%) + rewrite ds.h (88%) + rewrite edit.cpp (74%) + rewrite edit.h (77%) + rewrite filebuf.h (87%) + rewrite group_walk.h (85%) + rewrite ival_list.cpp (82%) + rewrite ival_list.h (80%) + rewrite ls.cpp (75%) + rewrite ls.h (86%) + create mode 100644 main.py + rewrite multikey_qsort.h (74%) + rewrite opts.h (88%) + rewrite outq.cpp (81%) + rewrite outq.h (67%) + rewrite pat.cpp (86%) + rewrite pat.h (84%) + rewrite pe.cpp (91%) + rewrite pe.h (77%) + rewrite presets.cpp (71%) + rewrite qual.cpp (74%) + rewrite qual.h (64%) + rewrite random_source.cpp (72%) + rewrite random_source.h (78%) + rewrite random_util.h (82%) + rewrite read.h (86%) + rewrite read_qseq.cpp (79%) + rewrite ref_coord.h (85%) + rewrite ref_read.cpp (81%) + rewrite ref_read.h (77%) + rewrite reference.cpp (88%) + rewrite reference.h (64%) + rewrite sam.cpp (92%) + rewrite sam.h (91%) + rewrite scoring.cpp (75%) + rewrite scoring.h (77%) + rewrite sequence_io.h (60%) + rewrite shmem.h (61%) + rewrite simple_func.cpp (63%) + rewrite sse_util.h (92%) + rewrite sstring.cpp (83%) + rewrite sstring.h (89%) + rewrite threading.h (62%) + rewrite threadpool.h (90%) + rewrite timer.h (62%) + rewrite unique.h (81%) + rewrite zstd_decompress.cpp (87%) +``` + +## 1.4.统计结果 + +综上信息,项目中代码规范性自检检查结果为 + +通过率 : 94.5% 1-125/84788*100% + +不通过率: 5.5 % 125/84788*100% + +## 2.功能性测试 + +### 2.1.所选测试案例 + +bowtie2在Makefile中内置两条测试命令,分别是simple-test和random-test,这里选取random-test。 + +random-test的测试命令如下: +```bash +eval `perl -I $(CURDIR)/.tmp/lib/perl5 -Mlocal::lib=$(CURDIR)/.tmp` ; \ +sh ./scripts/sim/run.sh $(if $(NUM_CORES), $(NUM_CORES), 2) + +## run.sh +CPUS=$1 +shift + +MAKE=`which gmake || which make` +$MAKE -j$CPUS \ + bowtie2-align-s \ + bowtie2-align-l \ + bowtie2-align-s-debug \ + bowtie2-align-l-debug \ + bowtie2-build-s \ + bowtie2-build-l \ + bowtie2-build-s-debug \ + bowtie2-build-l-debug && \ +perl scripts/sim/run.pl \ + --bowtie2=./bowtie2 \ + --bowtie2-build=./bowtie2-build \ + --cpus=$CPUS \ + $* +``` + +在项目根目录下执行命令来进行测试 +```bash +export NUM_CORES=1 +make random-test +``` + +### 2.2.运行结果 +```bash +[root@ecs-7567 bowtie2-2.4.5]# make random-test +if [ ! -d "/root/hpcrunner/tmp/bowtie2-2.4.5/.tmp" ]; then \ + mkdir -p /root/hpcrunner/tmp/bowtie2-2.4.5/.tmp/include /root/hpcrunner/tmp/bowtie2-2.4.5/.tmp/lib ; \ +fi +DL=$( ( which wget >/dev/null 2>&1 && echo "wget --no-check-certificate -O-" ) || echo "curl -L") ; \ +$DL http://cpanmin.us | perl - -l /root/hpcrunner/tmp/bowtie2-2.4.5/.tmp App::cpanminus local::lib ; \ +eval `perl -I /root/hpcrunner/tmp/bowtie2-2.4.5/.tmp/lib/perl5 -Mlocal::lib=/root/hpcrunner/tmp/bowtie2-2.4.5/.tmp` ; \ +/root/hpcrunner/tmp/bowtie2-2.4.5/.tmp/bin/cpanm --force File::Which Math::Random Clone Test::Deep Sys::Info ; \ +...... +Created DNA generator + N frac: 0.031 + IUPAC frac: 0.008 + AT/ACGT frac: 0.508 + A/AT frac: 0.526 + C/CG frac: 0.296 +Generating 2 references +Created DNA generator + N frac: 0.031 + IUPAC frac: 0.008 + AT/ACGT frac: 0.508 + A/AT frac: 0.526 + C/CG frac: 0.296 +Generating 2 references + Generated reference 'Sim.pm.1' of untrimmed length 308, trimmed length 276 + Generated reference 'Sim.pm.1' of untrimmed length 308, trimmed length 197 + Generated reference 'Sim.pm.2' of untrimmed length 364, trimmed length 85 +Wrote references to /tmp/Sim.pm.A3VQFNcf.fa + A: 87 + B: 1 + C: 61 + G: 123 + N: 7 + T: 81 + V: 1 +...... +170 reads; of these: + 170 (100.00%) were unpaired; of these: + 170 (100.00%) aligned 0 times + 0 (0.00%) aligned exactly 1 time + 0 (0.00%) aligned >1 times +0.00% overall alignment rate +diff -uw /tmp/Sim.pm.q2WhGHCp.als /tmp/Sim.pm.q2WhGHCp.debug.als +ALSO checking that bowtie2 and bowtie2 -p X w/ X > 1 match up +./bowtie2 --mm --large-index --cp-ival 1 --local --score-min L,7.34249013574406,1.76331087522275 --rfg 19.2968780660232,11.9325479307522 --cp-min 2 -q -p 3 -x /tmp/Sim.pm.q2WhGHCp /tmp/Sim.pm.q2WhGHCp_1.fastq | grep -v '^@PG' > /tmp/Sim.pm.q2WhGHCp.px.als +Warning: skipping read '5' because length (1) <= # seed mismatches (0) +Warning: skipping read '5' because it was < 2 characters long +Warning: skipping read '41' because length (1) <= # seed mismatches (0) +Warning: skipping read '41' because it was < 2 characters long +Warning: skipping read '157' because length (1) <= # seed mismatches (0) +Warning: skipping read '157' because it was < 2 characters long +170 reads; of these: + 170 (100.00%) were unpaired; of these: + 170 (100.00%) aligned 0 times + 0 (0.00%) aligned exactly 1 time + 0 (0.00%) aligned >1 times +0.00% overall alignment rate +sort -k 1,1 -n -k 2,2 -k 3,3 -k 4,4 < /tmp/Sim.pm.q2WhGHCp.px.als | grep -v '^@PG' > /tmp/Sim.pm.q2WhGHCp.px.als.sorted +sort -k 1,1 -n -k 2,2 -k 3,3 -k 4,4 < /tmp/Sim.pm.q2WhGHCp.debug.als | grep -v '^@PG' > /tmp/Sim.pm.q2WhGHCp.debug.als.sorted +diff -uw /tmp/Sim.pm.q2WhGHCp.debug.als.sorted /tmp/Sim.pm.q2WhGHCp.px.als.sorted +PASSED +``` + +由于测试输出结果过长,这里只显示了部分,感兴趣的同学可以自己安装进行测试。 + +## 3.性能测试 + +### 3.1.测试平台信息对比 + +| | arm信息 | x86信息 | +| -------- | --------------------------------------------- | --------------------------- | +| 操作系统 | openEuler 20.09 | openEuler 20.09 | +| 内核版本 | 4.19.90-2110.8.0.0119.oe1.aarch64 | 4.19.90-2003.4.0.0036.oe1.x86_64 | + +### 3.2.测试软件环境信息对比 + +| | arm信息 | x86信息 | +| ----- | ------------- | --------- | +| gcc | kgcc 9.3.1 | gcc 9.3.0 | +| bowtie2 | 2.4.5 | 2.4.5 | + +### 3.3.测试硬件性能信息对比 + +| | arm信息 | x86信息 | +| ------ | ----------- | ---------- | +| cpu | Kunpeng 920 | Intel(R) Xeon(R) Gold 6278C| +| 核心数 | 8 | 8 | +| 内存 | 16 GB | 16 GB | +| 磁盘io | 1.3 GB/s | 1.3 MB/s | +| 虚拟化 | KVM | KVM | + +### 3.4.单线程 +单线程运行测试时间对比(五次运行取平均值) +| | arm | x86 | +| -------------- | -------- | -------- | +| 实际CPU时间 | 3m2.592s | 1m46.784s | +| 用户时间 | 2m26.153s | 0m57.053s | + +### 3.5.多线程 + +多线程运行测试时间对比(五次运行取平均值) + +| | arm | x86 | +| ----------- | ---------- | --------- | +| 线程数 | 4 | 4 | +| 实际CPU时间 | 0m47.075s | 0m35.997s | +| 用户时间 | 0m7.956s | 0m16.749s | + +arm多线程时间耗费数据表: + +| 线程 | 1 | 2 | 4 | 8 | +| :------------ | -------- | ------- | -------- | ------- | +| 用户时间(s) | 182.592 | 172.340 | 116.716 | 180.501 | +| 用户态时间(s) | 146.153 | 218.942 | 272.470 | 837.371 | +| 内核态时间(s) | 13.765 | 26.512 | 53.088 | 96.164 | + +x86多线程时间耗费数据表: +| 线程 | 1 | 2 | 4 | 8 | +| :------------ | -------- | ------- | -------- | ------- | +| 用户时间(s) | 106.784 | 104.843 | 72.823 | 85.073 | +| 用户态时间(s) | 57.053 | 110.375 | 220.173 | 380.683 | +| 内核态时间(s) | 19.753 | 41.605 | 63.530 | 98.340 | + +测试效果取决网络的好坏,因此上述数据可以不做参考,但是从数据不难看出线程为4效果较好 + +## 4.精度测试 + +### 4.1.所选测试案例 + +scripts/sim下的run.pl文件 + +```perl +use strict; +use warnings; +use Getopt::Long; +use FindBin qw($Bin); +use lib "$Bin"; +use lib "$Bin/contrib"; +use Sim; +use ForkManager; + +# Simulator configuration +our %conf = ( + bowtie2_build => "bowtie2-build", + bowtie2 => "bowtie2", + bowtie2_build_debug => "bowtie2-build --debug", + bowtie2_debug => "bowtie2 --debug", + tempdir => "/tmp", + no_color => 1, + small => 1 +); + +# Number of parallel processes to use +my $cpus = 1; + +my $usage = qq! +run.pl [options*] + +Options: + + --bowtie2 Path to bowtie2 release binary + --bowtie2-debug Path to bowtie2 debug binary + --bowtie2-build Path to bowtie2-build release binary + --bowtie2-build-debug Path to bowtie2-build debug binary + --tempdir Put temporary files here + --cases Each thread runs around cases (def: 5) + --cpus / -p Run test cases in threads at once + --maxreads Handle at most reads per case + --numrefs Generate refs per case + --die-with-child Kill parent as soon as 1 child dies + --no-die-with-child Don\'t kill parent as soon as 1 child dies + --small Make small test cases + --help Print this usage message + +!; + +my $help = 0; +my $ncases = 5; +my $dieWithChild = 1; + +GetOptions( + "bowtie2=s" => \$conf{bowtie2}, + "bowtie2-build=s" => \$conf{bowtie2_build}, + "tempdir|tmpdir=s" => \$conf{tempdir}, + "cases-per-thread=i" => \$ncases, + "small" => \$conf{small}, + "large" => sub { $conf{small} = 0 }, + "no-paired" => \$conf{no_paired}, + "color" => sub { $conf{no_color} = 0 }, + "no-color" => \$conf{no_color}, + "help" => \$help, + "die-with-child" => \$dieWithChild, + "no-die-with-child" => sub { $dieWithChild = 0 }, + "p|cpus=i" => \$cpus, + "u|qupto|maxreads=i" => \$conf{maxreads}, + "numrefs|num-refs=i" => \$conf{numrefs}, +) || die "Bad options;"; + +if($help) { + print $usage; + exit 0; +} + +my $sim = Sim->new(); +my $pm = new Parallel::ForkManager($cpus); + +# Callback for when a child finishes so we can get its exit code +my @childFailed = (); +my @childFailedPid = (); + +$pm->run_on_finish(sub { + my ($pid, $exit_code, $ident) = @_; + if($exit_code != 0) { + push @childFailed, $exit_code; + push @childFailedPid, $pid; + !$dieWithChild || die "Dying with child with PID $pid"; + } +}); + +my $totcases = $ncases * $cpus; +for(1..$totcases) { + my $childPid = $pm->start; + if($childPid != 0) { + next; # spawn the next child + } + $sim->nextCase(\%conf); + $pm->finish; +} +$pm->wait_all_children; +for(@childFailedPid) { + print STDERR "Error message from child with pid $_:\n"; + my $fn = ".run.pl.child.$_"; + if(open(ER, $fn)) { + print STDERR "---------\n"; + while() { + print STDERR $_; + } + print STDERR "---------\n"; + close(ER); + } else { + print STDERR "(could not open $fn)\n"; + } +} +print STDERR "PASSED\n"; +``` + +### 4.2.获取对比数据 + +arm 运行结果(部分) + +```bash +156 reads; of these: + 156 (100.00%) were paired; of these: + 156 (100.00%) aligned concordantly 0 times + 0 (0.00%) aligned concordantly exactly 1 time + 0 (0.00%) aligned concordantly >1 times + ---- + 156 pairs aligned concordantly 0 times; of these: + 0 (0.00%) aligned discordantly 1 time + ---- + 156 pairs aligned 0 times concordantly or discordantly; of these: + 312 mates make up the pairs; of these: + 293 (93.91%) aligned 0 times + 16 (5.17%) aligned exactly 1 time + 3 (0.92%) aligned >1 times +6.09% overall alignment rate +diff -uw /tmp/Sim.pm.Sx0_YrOH.debug.als /tmp/Sim.pm.Sx0_YrOH.px.reord.als +PASSED +``` + +### 4.3.测试总结 +从arm输出结果可以看出测试通过,误差为0.92%,所有运算结果偏差在1%以内,偏差较小。 \ No newline at end of file diff --git "a/doc/bowtie2/\343\200\212\345\237\272\344\272\216openEuler\347\232\204bowtie2\350\275\257\344\273\266\347\247\273\346\244\215\346\214\207\345\215\227\343\200\213.md" "b/doc/bowtie2/\343\200\212\345\237\272\344\272\216openEuler\347\232\204bowtie2\350\275\257\344\273\266\347\247\273\346\244\215\346\214\207\345\215\227\343\200\213.md" new file mode 100644 index 0000000000000000000000000000000000000000..da7c0c0d6be1e74eaa50a6a62593ca8263de6d26 --- /dev/null +++ "b/doc/bowtie2/\343\200\212\345\237\272\344\272\216openEuler\347\232\204bowtie2\350\275\257\344\273\266\347\247\273\346\244\215\346\214\207\345\215\227\343\200\213.md" @@ -0,0 +1,261 @@ +# 《基于openEuler的bowtie2软件移植指南》 + +## 1.介绍 + +- Bowtie2是将测序reads与长参考序列比对工具(适用于将长度大约为50到100或1000字符的reads与相对较长的基因组,如哺乳动物基因组,进行比对)。通常是比较基因组学(包括识别变体(variation calling)、ChIP-seq、RNA-seq和BS-seq)管道的第一步。它可以处理非常长的读数(即10s或100s的千字节),但它针对近期测序仪产生的读数长度和误差模式进行了优化,如Illumina HiSeq 2000、Roche 454和Ion Torrent仪器。 + +- Bowtie2使用FM索引(基于Burrows-Wheeler Transform或BWT)对基因组进行索引,以此来保持其占用较小内存。对于人类基因组来说,内存占用在3.2G左右。 + +- 官网地址:http://bowtie-bio.sourceforge.net/bowtie2/manual.shtml + +- GITHUB托管地址:https://github.com/BenLangmead/bowtie2 + +- 特征: + + - 支持间隔 + - 局部和双端对齐模式 + - 可以同时使用多个处理器来极大的提升比对速度 + +## 2.环境要求 + +- 操作系统:openeuler arm/x86 (本文档以 x86 架构为例) + +## 3.配置编译环境 + +配置环境指导,手动进行配置依赖环境。 + +### 3.1.环境总览 + +- 编译器:gcc + +- 其他类库:`Cmake` + +- 具体版本和下载地址如下 + +| 名称 | 版本 | 软件下载地址 | +| -------- | ------ | ---------------------------------------------------------------------------------------------- | +| gcc | 9.3.0 | | +| CMake | 3.23.1 | | + +### 3.2.创建文件夹 + +```bash +mkdir -p $HOME/build +mkdir -p $HOME/install +mkdir -p $HOME/tmp +``` + +### 3.3.安装预设 + +设置环境变量,方便修改自定义安装目录 + +- 编译目录为 $HOME/build , 根据实际情况进行修改 +- 软件安装目录为 $HOME/install , 根据实际情况进行修改 +- 下载目录为 $HOME/tmp , 根据实际情况进行修改 + +```bash +#为了方便自定义软件安装目录 +#环境变量DEP_INSTALL_DIR将在后文中作为软件安装目录的根目录 +export DEP_INSTALL_DIR=$HOME/install +#环境变量DEP_BUILD_DIR将在后文中作为编译的根目录 +export DEP_BUILD_DIR=$HOME/build +#环境变量DEP_DOWNLOAD_DIR将在后文中作为下载文件的保存目录 +export DEP_DOWNLOAD_DIR=$HOME/tmp + +#注: 以上变量只在一次会话中有效。如果中途断开ssh会话,则在后续的安装过程中不会生效,需要重新运行 +``` + +### 3.4.安装环境依赖和gcc编译器 + +```bash +#环境依赖 +yum -y install gcc gcc-c++ wget tar libatomic + +#安装gcc编译器 +wget -P $DEP_DOWNLOAD_DIR https://ftp.gnu.org/gnu/gcc/gcc-9.3.0/gcc-9.3.0.tar.gz +tar -xf $DEP_DOWNLOAD_DIR/gcc-9.3.0.tar.gz -C $DEP_INSTALL_DIR +sed -i "35s/ftp/http/g" ./contrib/download_prerequisites +./contrib/download_prerequisites +./configure --disable-multilib --enable-languages="c,c++,fortran" --prefix=$1 --disable-static --enable-shared +make -j && make install +#设置环境变量 +echo "export PATH=$DEP_INSTALL_DIR/gcc-9.3.0/bin:$PATH" >> ~/.bashrc && source ~/.bashrc +export CC=`which gcc` +export CXX=`which g++` +``` + +### 3.5.下载并编译`CMake` + +```bash +# 下载CMake +wget https://github.com/Kitware/CMake/releases/download/v3.23.1/cmake-3.23.1-linux-x86_64.tar.gz -O $DEP_DOWNLOAD_DIR/cmake-3.23.1.tar.gz +tar -xvf $DEP_DOWNLOAD_DIR/cmake-3.23.1-linux-x86_64.tar.gz -C $DEP_INSTALL_DIR/cmake --strip-components=1 +echo "export PATH=$DEP_INSTALL_DIR/cmake/bin:$PATH" >> ~/.bashrc && source ~/.bashrc +``` + +## 4.编译bowtie2 + +### 4.1.下载并编译bowtie2 + +获取bowtie2软件源码并解压文件 +```bash +# 下载源码文件 +wget https://github.com/BenLangmead/bowtie2/archive/refs/tags/v2.4.5.tar.gz +# 解压源码文件 +tar -xvf $DEP_DOWNLOAD_DIR/v2.4.5.tar.gz -C $DEP_BUILD_DIR +cd $DEP_BUILD_DIR/bowtie2-2.4.5 +make -j +make static-libs -j && make STATIC_BUILD=1 -j +``` + +### 4.2. 运行测试文件 + +运行bowtie2项目测试文件 + +```bash +cd $DEP_BUILD_DIR/bowtie2-2.4.5 +make random-test +``` + +## 附A:使用hpcrunner进行一键安装BOWTIE2 + +推荐使用hpcrunner进行安装BOWTIE2 + +### 1.克隆仓库 + +```bash +git clone https://gitee.com/openeuler/hpcrunner.git +``` + +## 2.初始化hpcrunner 和 安装必要软件包 + +初始化项目助手 + +```bash +cd hpcrunner +source init.sh +``` + +安装必要软件包 + +**arm / x86 需要的软件包不同,根据实际环境进行选择** + +```bash +# arm +yum install -y environment-odules git wget unzip make flex tar +# x86 +yum install -y environment-modules git wget unzip make flex tar +yum install -y gcc gcc-c++ gcc-gfortran glibc-devel libgfortran +yum install -y tcsh tcl lsof tk bc +``` + +### 3.选择平台对应配置文件 + +- arm平台的配置文件为 `templates/bowtie2/2.4.5/data.bowtie2.arm.cpu.config` + + ```bash + ./jarvis -use templates/bowtie2/2.4.5/data.bowtie2.arm.cpu.config + ``` + +- x86 平台的配置文件为 `templates/bowtie2/2.4.5/data.bowtie2.x86.cpu.config` + + ```bash + ./jarvis -use templates/bowtie2/2.4.5/data.bowtie2.x86.cpu.config + ``` + +### 4.下载bowtie2源码 + +```bash +./jarvis -d +``` + +### 5.一键配置依赖环境 + +```bash +./jarvis -dp +``` + +### 6.一键进行编译 + +```bash +./jarvis -b +``` + +### 7.一键进行运行测试 + +```bash +./jarvis -r +``` + +## 附B:使用singularity运行容器 + +### 使用教程 + +### 下载容器镜像 + +通过链接下载: +[百度云盘](https://pan.baidu.com/s/1dh_Ns4HVR4KJ6J_yMfrh2A) +提取码: hjrf + +或者扫码下载: + +![百度云](data:image/jpeg;base64,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) + +#### 1.安装singularity + +安装singularity, + +具体步骤如下 + +```bash +mkdir -p ~/install +mkdir -p ~/build + +#安装编译所需依赖 +yum -y install libatomic libstdc++ libstdc++-devel libseccomp-devel glib2-devel gcc squashfs-tools tar + +#安装bisheng编译器 +cd ~/build +wget https://mirrors.huaweicloud.com/kunpeng/archive/compiler/bisheng_compiler/bisheng-compiler-2.1.0-aarch64-linux.tar.gz +tar -C ~/install -xf bisheng-compiler-2.1.0-aarch64-linux.tar.gz +echo "export PATH=$HOME/install/bisheng-compiler-2.1.0-aarch64-linux/bin:$PATH" >> ~/.bashrc && source ~/.bashrc +export CC=`which clang` +export CXX=`which clang++` + +#安装go编译器 +cd ~/build +wget https://go.dev/dl/go1.19.linux-arm64.tar.gz +tar -C ~/install -xf go1.19.linux-arm64.tar.gz +echo "export PATH=$HOME/install/go/bin:$PATH" >> ~/.bashrc && source ~/.bashrc + +#安装singularity +cd ~/build +wget https://github.com/sylabs/singularity/releases/download/v3.10.2/singularity-ce-3.10.2.tar.gz +tar -xf singularity-ce-3.10.2.tar.gz +cd singularity-ce-3.10.2 +./mconfig --prefix=$HOME/install/singularity +make -C ./builddir +make -C ./builddir install +echo "export PATH=$HOME/install/singularity/bin:$PATH" >> ~/.bashrc && source ~/.bashrc +``` + +#### 2.构建镜像 + +```shell +# x86 +singularity build ./name-of-image.sif openeuler-gcc-9.3.0-bowtie2-2.4.5.def +# arm +singularity build ./name-of-image.sif openeuler-bisheng2-9.3.1-bowtie2-2.4.5.def +# 转换为沙盒 +singularity build --sandbox image-sandbox name-of-image.sif +``` + +#### 3.在沙盒中运行 + +```shell +#进入沙盒 +singularity shell -w image-sandbox +#在沙盒中运行内置的测试案例 +cd /hpcrunner +./jarvis -r +``` \ No newline at end of file diff --git a/templates/bowtie2/2.4.5/data.bowtie2.arm.cpu.config b/templates/bowtie2/2.4.5/data.bowtie2.arm.cpu.config new file mode 100644 index 0000000000000000000000000000000000000000..716384f3322dfcadf68e6b2d66b36370d883942c --- /dev/null +++ b/templates/bowtie2/2.4.5/data.bowtie2.arm.cpu.config @@ -0,0 +1,44 @@ +[SERVER] +11.11.11.11 + +[DOWNLOAD] +bowtie2/2.4.5 https://github.com/BenLangmead/bowtie2/archive/refs/tags/v2.4.5.tar.gz + +[DEPENDENCY] +set -e +set -x +./jarvis -install bisheng/2.1.0 com +module purge +module use ./software/modulefiles +module load bisheng2/2.1.0 +cd ${JARVIS_TMP} +tar -xvf ${JARVIS_DOWNLOAD}/v2.4.5.tar.gz -C ${JARVIS_TMP} +cd ${JARVIS_TMP}/bowtie2-2.4.5 +sed -i 's/\CXXFLAGS += -std=c++11/\CXXFLAGS += -std=c++11 -stdlib=libc++/g' Makefile +wget https://github.com/simd-everywhere/simde/archive/refs/tags/v0.7.2.tar.gz +tar -xzf v0.7.2.tar.gz +cp -r simde-0.7.2/simde ./third_party + +[ENV] +module use ./software/modulefiles +module load bisheng2/2.1.0 +export CC=`which clang` +export CXX=`which clang++` +export FC=`which flang` + +[APP] +app_name = bowtie2 +build_dir = ${JARVIS_TMP}/bowtie2-2.4.5 +binary_dir = +case_dir = ${JARVIS_TMP}/bowtie2-2.4.5 + +[BUILD] +make -j +make static-libs -j && make STATIC_BUILD=1 -j +mkdir -p ${JARVIS_LIBS}/bisheng2/bowtie2/2.4.5/bin +cp bowtie2* ${JARVIS_LIBS}/bisheng2/bowtie2/2.4.5/bin + +[RUN] +run = make random-test +binary = +nodes = 1 \ No newline at end of file diff --git a/templates/bowtie2/2.4.5/data.bowtie2.x86.cpu.config b/templates/bowtie2/2.4.5/data.bowtie2.x86.cpu.config new file mode 100644 index 0000000000000000000000000000000000000000..47d5e2ac01d6307f1d093732d531e27b85b44956 --- /dev/null +++ b/templates/bowtie2/2.4.5/data.bowtie2.x86.cpu.config @@ -0,0 +1,38 @@ +[SERVER] +11.11.11.11 + +[DOWNLOAD] +bowtie2/2.4.5 https://github.com/BenLangmead/bowtie2/archive/refs/tags/v2.4.5.tar.gz + +[DEPENDENCY] +set -e +set -x +module purge +./jarvis -install gcc/9.3.0 com +module use ${JARVIS_ROOT}/software/modulefiles +module load gcc9/9.3.0 +cd ${JARVIS_TMP} +tar -xvf ${JARVIS_DOWNLOAD}/v2.4.5.tar.gz -C ${JARVIS_TMP} + +[ENV] +module purge +module use ${JARVIS_ROOT}/software/modulefiles +module load gcc9/9.3.0 + + +[APP] +app_name = bowtie2 +build_dir = ${JARVIS_TMP}/bowtie2-2.4.5 +binary_dir = ${JARVIS_LIBS}/bowtie2-2.4.5/bin +case_dir = ${JARVIS_TMP}/bowtie2-2.4.5 + +[BUILD] +make -j +make static-libs -j && make STATIC_BUILD=1 -j +mkdir -p ${JARVIS_LIBS}/gcc9/bowtie2/2.4.5/bin +cp bowtie2* ${JARVIS_LIBS}/gcc9/bowtie2/2.4.5/bin + +[RUN] +run = make random-test +binary = +nodes = 1 \ No newline at end of file diff --git a/test/test-bowtie2.sh b/test/test-bowtie2.sh new file mode 100644 index 0000000000000000000000000000000000000000..ce74a42bfc886b0627e06807c75b0838b915e7d5 --- /dev/null +++ b/test/test-bowtie2.sh @@ -0,0 +1,16 @@ +#!/bin/bash +cd .. +# release bowtie2 src code +rm -rf tmp/bowtie2-2.4.5 +# copy templates +cp -rf templates/bowtie2/2.4.5/data.bowtie2.x86.cpu.config ./ +# switch to config +./jarvis -use data.bowtie2.x86.cpu.config +# download bowtie2 src code +./jarvis -d +# install dependency +./jarvis -dp +# build +./jarvis -b +# run +./jarvis -r \ No newline at end of file