[med-svn] [Git][med-team/spoa][upstream] New upstream version 4.1.4
Michael R. Crusoe (@crusoe)
gitlab at salsa.debian.org
Thu Mar 21 11:58:26 GMT 2024
Michael R. Crusoe pushed to branch upstream at Debian Med / spoa
Commits:
ccf4f105 by Michael R. Crusoe at 2024-03-21T12:23:32+01:00
New upstream version 4.1.4
- - - - -
28 changed files:
- + .github/workflows/spoa.yml
- .gitignore
- − .travis.yml
- CMakeLists.txt
- README.md
- + include/meson.build
- include/spoa/graph.hpp
- include/spoa/spoa.hpp
- + include/spoa/version.hpp
- + meson.build
- + meson_options.txt
- include/spoa/architectures.hpp → src/architectures.hpp
- src/graph.cpp
- src/main.cpp
- + src/meson.build
- src/simd_alignment_engine.hpp
- src/simd_alignment_engine_dispatcher.cpp
- src/simd_alignment_engine_implementation.hpp
- + src/spoa_config.h.in
- + src/version.cpp
- + subprojects/bioparser.wrap
- + subprojects/biosoup.wrap
- + subprojects/cereal.wrap
- + subprojects/gtest.wrap
- + subprojects/simde.wrap
- + test/meson.build
- test/spoa_test.cpp
- + test/spoa_test_config.h.in
Changes:
=====================================
.github/workflows/spoa.yml
=====================================
@@ -0,0 +1,68 @@
+name: spoa CI
+
+on:
+ push:
+ pull_request:
+ branches:
+ - master
+
+env:
+ BUILD_TYPE: Release
+
+jobs:
+ test:
+ strategy:
+ matrix:
+ compiler:
+ - g++-7
+ - g++
+ - clang++-6.0
+ - clang++
+
+ runs-on: ubuntu-20.04
+
+ steps:
+ - uses: actions/checkout at v3
+
+ - if: ${{ contains(matrix.compiler, '-') }}
+ name: Get compiler version
+ id: get-compiler-version
+ run: |
+ version=$(echo ${{ matrix.compiler }} | cut -d- -f2)
+ echo "version=$version" >> $GITHUB_OUTPUT
+
+ - if: ${{ startsWith(matrix.compiler, 'g++-') }}
+ name: Setup GCC
+ uses: egor-tensin/setup-gcc at v1
+ with:
+ version: "${{ steps.get-compiler-version.outputs.version }}"
+ platform: x64
+
+ - if: ${{ startsWith(matrix.compiler, 'clang++-') }}
+ name: Setup Clang
+ uses: egor-tensin/setup-clang at v1
+ with:
+ version: "${{ steps.get-compiler-version.outputs.version }}"
+ platform: x64
+
+ - name: Configure CMake
+ run: |
+ cmake -B ${{ github.workspace }}/build_cmake -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }}
+ cmake --build ${{ github.workspace }}/build_cmake
+ env:
+ CXX: ${{ matrix.compiler }}
+
+ - name: Configure Meson
+ uses: BSFishy/meson-build at v1.0.3
+ with:
+ action: build
+ directory: build_meson
+ meson-version: 0.60.0
+
+ - name: Test
+ working-directory: ${{ github.workspace }}
+ run: |
+ build_cmake/bin/spoa --version
+ build_cmake/bin/spoa_test
+ build_meson/src/spoa --version
+ build_meson/test/spoa_test
=====================================
.gitignore
=====================================
@@ -1,2 +1,5 @@
# Compiled Object files
build/
+
+/subprojects/*
+!/subprojects/*.wrap
=====================================
.travis.yml deleted
=====================================
@@ -1,44 +0,0 @@
-language: cpp
-
-matrix:
- include:
- - name: "GCC 4.8 (Linux)" # GCC 4.8.5 & CMake 3.12.4
- os: linux
- dist: xenial
- addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- packages:
- - g++-4.8
- env:
- - SET_COMPILER="export CC=gcc-4.8 && export CXX=g++-4.8"
-
- - name: "Clang 3.5 (Linux)" # Clang 3.5.0 & CMake 3.12.4
- os: linux
- dist: xenial
- addons:
- apt:
- packages:
- - clang-3.5
- env:
- - SET_COMPILER="export CC=clang-3.5 && export CXX=clang++-3.5"
-
- - name: "Clang Xcode 9.4 (OSX)" # Clang 9.4.1 & CMake 3.15.5
- os: osx
- osx_image: xcode9.4
-
-before_install:
- - eval "${SET_COMPILER}"
-
-install:
- - mkdir build && cd build
- - cmake -DCMAKE_BUILD_TYPE=Release .. && make
-
-script:
- - ./bin/spoa --version
- - ./bin/spoa_test
-
-notifications:
- email:
- on_failure: always
=====================================
CMakeLists.txt
=====================================
@@ -1,23 +1,14 @@
cmake_minimum_required(VERSION 3.12)
-project(spoa VERSION 4.0.8
+project(spoa VERSION 4.1.4
LANGUAGES CXX
DESCRIPTION "Spoa is a c++ library (and tool) for SIMD vectorized partial order alignment.")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic")
-set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
-if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
- if (${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER_EQUAL "5.0.0")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-aligned-new")
- endif ()
- if (${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER_EQUAL "6.1.0")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-ignored-attributes")
- endif ()
-endif ()
-
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
@@ -55,7 +46,7 @@ if (spoa_use_simde OR
FetchContent_Declare(
simde
GIT_REPOSITORY https://github.com/simd-everywhere/simde
- GIT_TAG v0.7.0)
+ GIT_TAG v0.7.6)
FetchContent_GetProperties(simde)
if (NOT simde_POPULATED)
@@ -125,14 +116,14 @@ if (spoa_use_cereal)
endif ()
if (spoa_build_exe OR spoa_build_tests)
- find_package(bioparser 3.0.13 QUIET)
- find_package(biosoup 0.10.0 QUIET)
+ find_package(bioparser 3.1.0 QUIET)
+ find_package(biosoup 0.11.0 QUIET)
if (NOT bioparser_FOUND)
FetchContent_Declare(
bioparser
GIT_REPOSITORY https://github.com/rvaser/bioparser
- GIT_TAG 3.0.13)
+ GIT_TAG 3.1.0)
FetchContent_GetProperties(bioparser)
if (NOT bioparser_POPULATED)
@@ -148,7 +139,7 @@ if (spoa_build_exe OR spoa_build_tests)
FetchContent_Declare(
biosoup
GIT_REPOSITORY https://github.com/rvaser/biosoup
- GIT_TAG 0.10.0)
+ GIT_TAG 0.11.0)
FetchContent_GetProperties(biosoup)
if (NOT biosoup_POPULATED)
@@ -181,15 +172,20 @@ if (spoa_build_tests)
endif ()
endif ()
+set(SPOA_VERSION "${PROJECT_VERSION}")
+configure_file(src/spoa_config.h.in spoa_config.h)
+
add_library(spoa
src/alignment_engine.cpp
src/graph.cpp
src/simd_alignment_engine_dispatcher.cpp
- src/sisd_alignment_engine.cpp)
+ src/sisd_alignment_engine.cpp
+ src/version.cpp)
add_library(spoa::spoa ALIAS spoa)
target_include_directories(spoa PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
$<BUILD_INTERFACE:${simde_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)
@@ -267,13 +263,15 @@ if (spoa_build_exe)
bioparser::bioparser
biosoup::biosoup)
- target_compile_definitions(spoa_exe PRIVATE VERSION="${PROJECT_VERSION}")
set_property(TARGET spoa_exe PROPERTY OUTPUT_NAME spoa)
install(TARGETS spoa_exe DESTINATION ${CMAKE_INSTALL_BINDIR})
endif ()
if (spoa_build_tests)
+ set(SPOA_TEST_DATA "${PROJECT_SOURCE_DIR}/test/data/sample.fastq.gz")
+ configure_file(test/spoa_test_config.h.in spoa_test_config.h)
+
add_executable(spoa_test
test/spoa_test.cpp)
@@ -283,6 +281,6 @@ if (spoa_build_tests)
biosoup::biosoup
GTest::Main)
- target_compile_definitions(spoa_test
- PRIVATE TEST_DATA="${PROJECT_SOURCE_DIR}/test/data/sample.fastq.gz")
+ target_include_directories(spoa_test PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
endif ()
=====================================
README.md
=====================================
@@ -1,21 +1,69 @@
# Spoa
[![Latest GitHub release](https://img.shields.io/github/release/rvaser/spoa.svg)](https://github.com/rvaser/spoa/releases/latest)
-[![Build status for gcc/clang](https://travis-ci.com/rvaser/spoa.svg?branch=master)](https://travis-ci.com/rvaser/spoa)
+![Build status for gcc/clang](https://github.com/rvaser/spoa/actions/workflows/spoa.yml/badge.svg)
[![Published in Genome Research](https://img.shields.io/badge/published%20in-Genome%20Research-blue.svg)](https://doi.org/10.1101/gr.214270.116)
Spoa (SIMD POA) is a c++ implementation of the partial order alignment (POA) algorithm (as described in 10.1093/bioinformatics/18.3.452) which is used to generate consensus sequences (as described in 10.1093/bioinformatics/btg109). It supports three alignment modes: local (Smith-Waterman), global (Needleman-Wunsch) and semi-global alignment (overlap), and three gap modes: linear, affine and convex (piecewise affine). It also supports Intel SSE4.1+ and AVX2 vectorization (marginally faster due to high latency shifts), [SIMDe](https://github.com/simd-everywhere/simde) and dispatching.
-## Usage
+## Build
+
+### Dependencies
+
+- gcc 7+ | clang 4+
+- (spoa_exe)(spoa_test) zlib 1.2.8+
+
+#### Hidden
+
+- \[optional\] USCiLab/cereal 1.3.0
+- \[optional\] simd-everywhere/simde 0.7.6
+- \[optional\] google/cpu_features 0.6.0
+- (spoa_exe)(spoa_test) rvaser/bioparser 3.1.0
+- (spoa_exe)(spoa_test) rvaser/biosoup 0.11.0
+- (spoa_test) google/googletest 1.10.0
+
+### CMake (3.12+)
+
+```bash
+git clone https://github.com/rvaser/spoa && cd spoa
+cmake -B build -DCMAKE_BUILD_TYPE=Release
+make -C build
+```
+
+#### Options
-To build spoa run the following commands:
+- `spoa_install`: generate library install target
+- `spoa_build_exe`: build executable
+- `spoa_build_tests`: build unit tests
+- `spoa_optimize_for_native`: build with `-march=native`
+- `spoa_optimize_for_portability`: build with `-msse4.1`
+- `spoa_use_cereal`: use cereal library
+- `spoa_use_simde`: build with SIMDe for porting vectorized code
+- `spoa_use_simde_nonvec`: use SIMDe library for nonvectorized code
+- `spoa_use_simde_openmp`: use SIMDe support for OpenMP SIMD
+- `spoa_generate_dispatch`: use SIMDe to generate x86 dispatch
+
+### Meson (0.60.0+)
```bash
-git clone https://github.com/rvaser/spoa && cd spoa && mkdir build && cd build
-cmake -DCMAKE_BUILD_TYPE=Release .. && make
+git clone https://github.com/rvaser/spoa && cd spoa
+meson setup build
+ninja -C build
```
-which will create spoa library, executable and unit tests. Running the executable will display the following usage:
+#### Options
+
+- `exe`: build executable
+- `tests`: build unit tests
+- `avx2`: build with `-mavx2`
+- `sse41`: build with `-msse4.1`
+- `cereal`: build serialization funcitons
+- `simde`: build with SIMDe
+- `simde_nonvec`: use SIMDe for nonvectorized code
+- `simde_openmp`: use SIMDe support for OpenMP SIMD
+- `dispatch`: use SIMDe to generate x86 dispatch
+
+## Usage
```bash
usage: spoa [options ...] <sequences>
@@ -74,48 +122,6 @@ usage: spoa [options ...] <sequences>
convex otherwise (default)
```
-Running `make install` will install the library and the executable. If you choose to build with cereal or want to generate the dispatcher, cereal and cpu_features (see Dependencies) need to be installed beforehand, respectively. Once the library is installed, with or without additional options, a package will be copied to your system that can be searched and linked with:
-
-```cmake
-find_package(spoa)
-target_link_libraries(<target> spoa::spoa)
-```
-
-On the other hand, you can include spoa as a submodule and add it to your project with the following:
-
-```cmake
-if (NOT TARGET spoa)
- add_subdirectory(<path_to_submodules>/spoa EXCLUDE_FROM_ALL)
-endif ()
-target_link_libraries(<target> spoa::spoa)
-```
-
-#### Build options
-
-- `spoa_install`: generate library install target
-- `spoa_build_exe`: build executable
-- `spoa_build_tests`: build unit tests
-- `spoa_optimize_for_native`: build with `-march=native`
-- `spoa_optimize_for_portability`: build with `-msse4.1`
-- `spoa_use_cereal`: use cereal library
-- `spoa_use_simde`: build with SIMDe for porting vectorized code
-- `spoa_use_simde_nonvec`: use SIMDe library for nonvectorized code
-- `spoa_use_simde_openmp`: use SIMDe support for OpenMP SIMD
-- `spoa_generate_dispatch`: use SIMDe to generate x86 dispatch
-
-#### Dependencies
-- gcc 4.8+ | clang 3.5+
-- cmake 3.12+
-- (spoa_exe)(spoa_test) zlib 1.2.8+
-
-###### Hidden
-- (optional) USCiLab/cereal 1.3.0
-- (optional) simd-everywhere/simde 0.7.0
-- (optional) google/cpu_features 0.6.0
-- (spoa_exe)(spoa_test) rvaser/bioparser 3.0.13
-- (spoa_exe)(spoa_test) rvaser/biosoup 0.10.0
-- (spoa_test) google/googletest 1.10.0
-
## Examples
```cpp
=====================================
include/meson.build
=====================================
@@ -0,0 +1,18 @@
+###########
+# Headers #
+###########
+
+spoa_include_directories = include_directories(['.'])
+
+if meson.is_subproject()
+ subdir_done()
+endif
+
+install_headers(
+ files([
+ 'spoa/alignment_engine.hpp',
+ 'spoa/graph.hpp',
+ 'spoa/spoa.hpp',
+ 'spoa/version.hpp',
+ ]),
+ subdir : 'spoa')
=====================================
include/spoa/graph.hpp
=====================================
@@ -166,6 +166,12 @@ class Graph {
std::string GenerateConsensus();
+ std::string GenerateConsensus(std::int32_t min_coverage);
+
+ std::string GenerateConsensus(
+ std::int32_t min_coverage,
+ std::vector<std::uint32_t> *summary);
+
std::string GenerateConsensus(
std::vector<std::uint32_t>* summary,
bool verbose = false);
=====================================
include/spoa/spoa.hpp
=====================================
@@ -5,5 +5,6 @@
#include "graph.hpp"
#include "alignment_engine.hpp"
+#include "version.hpp"
#endif // SPOA_SPOA_HPP_
=====================================
include/spoa/version.hpp
=====================================
@@ -0,0 +1,14 @@
+// Copyright (c) 2023 Robert Vaser
+
+#ifndef SPOA_VERSION_HPP_
+#define SPOA_VERSION_HPP_
+
+#include <string>
+
+namespace spoa {
+
+std::string Version();
+
+} // namespace spoa
+
+#endif // SPOA_VERSION_HPP_
=====================================
meson.build
=====================================
@@ -0,0 +1,111 @@
+project(
+ 'spoa',
+ ['cpp'],
+ version : '4.1.4',
+ default_options : [
+ 'buildtype=release',
+ 'warning_level=3',
+ 'cpp_std=c++17',
+ 'b_ndebug=if-release'],
+ license : 'MIT',
+ meson_version : '>=0.60.0'
+)
+
+################
+# Dependencies #
+################
+
+spoa_lib_flags = []
+spoa_lib_deps = []
+
+if get_option('cereal')
+ # cereal
+ spoa_cereal_dep = dependency('cereal', version : '>= 1.3.0', fallback : ['cereal', 'cereal_dep'])
+
+ spoa_lib_flags += '-DSPOA_USE_CEREAL'
+ spoa_lib_deps += spoa_cereal_dep
+endif
+
+if (not meson.is_subproject()) and (get_option('exe') or get_option('tests'))
+ # biosoup
+ spoa_biosoup_dep = dependency('biosoup', version : '>= 0.11.0', fallback : ['biosoup', 'biosoup_dep'])
+
+ # bioparser
+ spoa_bioparser_dep = dependency('bioparser', version : '>= 3.1.0', fallback : ['bioparser', 'bioparser_dep'])
+endif
+
+if not get_option('dispatch')
+ if get_option('sse41')
+ spoa_lib_flags += '-msse4.1'
+ elif get_option('avx2')
+ spoa_lib_flags += '-mavx2'
+ endif
+endif
+
+if (get_option('simde') or
+ get_option('simde_nonvec') or
+ get_option('simde_openmp') or
+ get_option('dispatch'))
+ # simde
+ spoa_simde_dep = dependency('simde', version : '>= 0.7.6', fallback : ['simde', 'simde_dep'])
+
+ add_project_arguments('-DSIMDE_ENABLE_NATIVE_ALIASES', language : ['c', 'cpp'])
+ spoa_lib_flags += '-DSPOA_USE_SIMDE'
+ spoa_lib_deps += spoa_simde_dep
+
+ if get_option('simde_nonvec')
+ add_project_arguments('-DSIMDE_NO_NATIVE', language : ['c', 'cpp'])
+ endif
+
+ if get_option('simde_openmp')
+ add_project_arguments('-DSIMDE_ENABLE_OPENMP', language : ['c', 'cpp'])
+ spoa_lib_flags += '-fopenmp-simd'
+ endif
+
+ if get_option('dispatch')
+ spoa_lib_flags += '-DSPOA_GENERATE_DISPATCH_CPUIDEX'
+ endif
+endif
+
+###########
+# Headers #
+###########
+
+subdir('include')
+
+###########
+# Sources #
+###########
+
+subdir('src')
+
+#########
+# Tests #
+#########
+
+if (not meson.is_subproject()) and get_option('tests')
+ # gtest
+ spoa_gtest_dep = dependency('gtest', version : '>= 1.10.0', main : true, fallback : ['gtest', 'gtest_main_dep'])
+
+ subdir('test')
+endif
+
+###################
+# Dependency info #
+###################
+
+if (not meson.is_subproject())
+ import('pkgconfig').generate(
+ spoa_lib,
+ name : 'spoa',
+ version : meson.project_version(),
+ filebase : 'spoa',
+ description : 'C++ tool/library for SIMD vectorized partial order alignment.')
+endif
+
+spoa_dep = declare_dependency(
+ include_directories : spoa_include_directories,
+ link_with : spoa_lib,
+ dependencies : spoa_lib_deps,
+ version : meson.project_version()
+)
=====================================
meson_options.txt
=====================================
@@ -0,0 +1,56 @@
+#################
+# Build options #
+#################
+
+option('cereal',
+ type : 'boolean',
+ value : false,
+ description : 'Enable serialization through cereal')
+
+option('avx2',
+ type : 'boolean',
+ value : false,
+ description : 'Build with -mavx2')
+
+option('sse41',
+ type : 'boolean',
+ value : false,
+ description : 'Build with -msse4.1')
+
+option('simde',
+ type : 'boolean',
+ value : false,
+ description : 'Build with SIMDe')
+
+option('simde_nonvec',
+ type : 'boolean',
+ value : false,
+ description : 'Use SIMDe for nonvectorized code')
+
+option('simde_openmp',
+ type : 'boolean',
+ value : false,
+ description : 'Use SIMDe support for OpenMP SIMD')
+
+option('dispatch',
+ type : 'boolean',
+ value : false,
+ description : 'Use SIMDe to generate x86 dispatch')
+
+##############
+# Executable #
+##############
+
+option('exe',
+ type : 'boolean',
+ value : true,
+ description : 'Build spoa executable')
+
+#########
+# Tests #
+#########
+
+option('tests',
+ type : 'boolean',
+ value : true,
+ description : 'Enable dependencies required for testing')
=====================================
include/spoa/architectures.hpp → src/architectures.hpp
=====================================
=====================================
src/graph.cpp
=====================================
@@ -374,6 +374,39 @@ std::string Graph::GenerateConsensus() {
return dst;
}
+std::string Graph::GenerateConsensus(std::int32_t min_coverage) {
+ TraverseHeaviestBundle();
+ std::string dst{};
+ for (const auto& it : consensus_) {
+ if (static_cast<std::int32_t>(it->Coverage()) >= min_coverage) {
+ dst += decoder_[it->code];
+ }
+ }
+ return dst;
+}
+
+std::string Graph::GenerateConsensus(std::int32_t min_coverage,
+ std::vector<std::uint32_t> *summary) {
+ if (!summary) {
+ throw std::invalid_argument(
+ "[spoa::Graph::GenerateConsensus] error: invalid ptr to summary");
+ }
+ summary->clear();
+
+ auto dst = GenerateConsensus(min_coverage);
+ for (const auto &it : consensus_) {
+ if (static_cast<std::int32_t>(it->Coverage()) >= min_coverage) {
+ summary->emplace_back(0);
+ summary->back() += it->Coverage();
+ for (const auto &jt : it->aligned_nodes) {
+ summary->back() += jt->Coverage();
+ }
+ }
+ }
+
+ return dst;
+}
+
std::string Graph::GenerateConsensus(
std::vector<std::uint32_t>* summary,
bool verbose) {
=====================================
src/main.cpp
=====================================
@@ -15,6 +15,7 @@ namespace {
static struct option options[] = {
{"algorithm", required_argument, nullptr, 'l'},
{"result", required_argument, nullptr, 'r'},
+ {"min-coverage", required_argument, nullptr, 'M'},
{"dot", required_argument, nullptr, 'd'},
{"strand-ambiguous", no_argument, nullptr, 's'},
{"version", no_argument, nullptr, 'v'},
@@ -101,6 +102,9 @@ void Help() {
" 2 - 0 & 1 (FASTA)\n"
" 3 - partial order graph (GFA)\n"
" 4 - 0 & 3 (GFA)\n"
+ " --min-coverage <int>\n"
+ " default: -1\n"
+ " minimal consensus coverage (usable only with -r 0)\n"
" -d, --dot <file>\n"
" output file for the partial order graph in DOT format\n"
" -s, --strand-ambiguous\n"
@@ -208,6 +212,8 @@ int main(int argc, char** argv) {
std::int8_t q = -10;
std::int8_t c = -4;
+ std::int32_t min_coverage = -1;
+
std::uint8_t algorithm = 0;
std::vector<std::uint8_t> results = { 0 };
std::string dot_path{};
@@ -223,11 +229,12 @@ int main(int argc, char** argv) {
case 'e': e = atoi(optarg); break;
case 'q': q = atoi(optarg); break;
case 'c': c = atoi(optarg); break;
+ case 'M': min_coverage = atoi(optarg); break;
case 'l': algorithm = atoi(optarg); break;
case 'r': results.emplace_back(atoi(optarg)); break;
case 'd': dot_path = optarg; break;
case 's': is_strand_ambiguous = true; break;
- case 'v': std::cout << VERSION << std::endl; return 0;
+ case 'v': std::cout << spoa::Version() << std::endl; return 0;
case 'h': Help(); return 0;
default: return 1;
}
@@ -316,7 +323,7 @@ int main(int argc, char** argv) {
for (const auto& it : results) {
switch (it) {
case 0: {
- auto consensus = graph.GenerateConsensus();
+ auto consensus = graph.GenerateConsensus(min_coverage);
std::cout << ">Consensus LN:i:" << consensus.size() << std::endl
<< consensus << std::endl;
break;
=====================================
src/meson.build
=====================================
@@ -0,0 +1,68 @@
+spoa_config = configuration_data()
+spoa_config.set('SPOA_VERSION', meson.project_version())
+
+###########
+# Library #
+###########
+
+spoa_config_headers = [
+ configure_file(
+ input : 'spoa_config.h.in',
+ output : 'spoa_config.h',
+ configuration : spoa_config)
+]
+
+spoa_sources = files([
+ 'alignment_engine.cpp',
+ 'graph.cpp',
+ 'simd_alignment_engine_dispatcher.cpp',
+ 'sisd_alignment_engine.cpp',
+ 'version.cpp',
+]) + spoa_config_headers
+
+spoa_simd_lib = []
+
+if get_option('dispatch')
+ simd = import('unstable_simd')
+
+ spoa_simd_sources = files([
+ 'simd_alignment_engine_dispatch.cpp',
+ ])
+
+ spoa_simd_lib += simd.check(
+ 'spoa',
+ sse2 : spoa_simd_sources,
+ sse41 : spoa_simd_sources,
+ avx2 : spoa_simd_sources,
+ dependencies : spoa_lib_deps,
+ include_directories : spoa_include_directories,
+ cpp_args : spoa_lib_flags,
+ compiler : meson.get_compiler('cpp'))[0]
+endif
+
+spoa_lib_install = (not meson.is_subproject()) or (get_option('default_library') != 'static')
+
+spoa_lib = library(
+ 'spoa',
+ spoa_sources,
+ soversion : meson.project_version(),
+ version : meson.project_version(),
+ install : spoa_lib_install,
+ dependencies : spoa_lib_deps,
+ include_directories : spoa_include_directories,
+ link_with : spoa_simd_lib,
+ cpp_args : spoa_lib_flags)
+
+##############
+# Executable #
+##############
+
+if (not meson.is_subproject()) and get_option('exe')
+ spoa_exe = executable(
+ 'spoa',
+ files(['main.cpp']),
+ install : true,
+ dependencies : [spoa_lib_deps, spoa_biosoup_dep, spoa_bioparser_dep],
+ include_directories : spoa_include_directories,
+ link_with : spoa_lib)
+endif
=====================================
src/simd_alignment_engine.hpp
=====================================
@@ -9,7 +9,7 @@
#include <vector>
#include "spoa/alignment_engine.hpp"
-#include "spoa/architectures.hpp"
+#include "architectures.hpp"
namespace spoa {
=====================================
src/simd_alignment_engine_dispatcher.cpp
=====================================
@@ -2,18 +2,78 @@
#include "simd_alignment_engine_implementation.hpp"
-#ifdef SPOA_GENERATE_DISPATCH
+#if defined(SPOA_GENERATE_DISPATCH)
#include "cpuinfo_x86.h" // NOLINT
static const cpu_features::X86Features features =
cpu_features::GetX86Info().features;
+#elif defined(SPOA_GENERATE_DISPATCH_CPUIDEX)
+
+# if defined(_MSC_VER)
+
+#include <intrin.h>
+
+# endif
+
+// adapted from https://github.com/intel/linux-sgx/blob/master/common/inc/internal/linux/cpuid_gnu.h
+void RunCpuidex(int cpu_info[4], int function_id, int subfunction_id) {
+# if defined(_MSC_VER)
+ __cpuidex(cpu_info, function_id, subfunction_id);
+# elif defined(__X86_64__)
+ __asm__ volatile ("cpuid")
+ : "=a" (cpu_info[0]), "=b" (cpu_info[1]), "=c" (cpu_info[2]), "=d" (cpu_info[3])
+ : "0" (function_id), "2" (subfunction_id));
+# else
+ __asm__ volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
+ : "=a" (cpu_info[0]), "=r" (cpu_info[1]), "=c" (cpu_info[2]), "=d" (cpu_info[3])
+ : "0" (function_id), "2" (subfunction_id));
+# endif
+}
+
+constexpr int SPOA_SSE2 = 0x1;
+constexpr int SPOA_SSE4_1 = 0x2;
+constexpr int SPOA_AVX2 = 0x4;
+
+static int GetX86Info() {
+ int cpu_info[4] = {0};
+
+ RunCpuidex(cpu_info, 0, 0);
+
+ const int n = cpu_info[0];
+ if (n == 0) {
+ return 0;
+ }
+
+ RunCpuidex(cpu_info, 1, 0);
+
+ int features = 0;
+ if (cpu_info[3] >> 26) {
+ features |= SPOA_SSE2;
+ }
+ if (cpu_info[2] >> 19) {
+ features |= SPOA_SSE4_1;
+ }
+
+ if (n >= 7) {
+ RunCpuidex(cpu_info, 7, 0);
+
+ if (cpu_info[1] >> 5) {
+ features |= SPOA_AVX2;
+ }
+ }
+
+ return features;
+}
+
+static const int features = GetX86Info();
+
#endif
namespace spoa {
-
-#ifndef SPOA_GENERATE_DISPATCH
+
+#if !defined(SPOA_GENERATE_DISPATCH) && !defined(SPOA_GENERATE_DISPATCH_CPUIDEX)
template class SimdAlignmentEngine<Architecture::kAutomatic>;
@@ -28,7 +88,7 @@ std::unique_ptr<AlignmentEngine> CreateSimdAlignmentEngine(
std::int8_t e,
std::int8_t q,
std::int8_t c) {
-#ifdef SPOA_GENERATE_DISPATCH
+#if defined(SPOA_GENERATE_DISPATCH)
if (features.avx2) {
return SimdAlignmentEngine<Architecture::kAVX2>::Create(
type, subtype, m, n, g, e, q, c);
@@ -39,6 +99,17 @@ std::unique_ptr<AlignmentEngine> CreateSimdAlignmentEngine(
return SimdAlignmentEngine<Architecture::kSSE2>::Create(
type, subtype, m, n, g, e, q, c);
}
+#elif defined(SPOA_GENERATE_DISPATCH_CPUIDEX)
+ if (features & SPOA_AVX2) {
+ return SimdAlignmentEngine<Architecture::kAVX2>::Create(
+ type, subtype, m, n, g, e, q, c);
+ } else if (features & SPOA_SSE4_1) {
+ return SimdAlignmentEngine<Architecture::kSSE4_1>::Create(
+ type, subtype, m, n, g, e, q, c);
+ } else {
+ return SimdAlignmentEngine<Architecture::kSSE2>::Create(
+ type, subtype, m, n, g, e, q, c);
+ }
#else
return SimdAlignmentEngine<Architecture::kAutomatic>::Create(
type, subtype, m, n, g, e, q, c);
=====================================
src/simd_alignment_engine_implementation.hpp
=====================================
@@ -29,34 +29,6 @@ extern "C" {
namespace spoa {
-// Taken from https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=216149
-inline void* align(
- std::size_t __align,
- std::size_t __size,
- void*& __ptr, // NOLINT
- std::size_t& __space) noexcept { // NOLINT
- const auto __intptr = reinterpret_cast<uintptr_t>(__ptr);
- const auto __aligned = (__intptr - 1u + __align) & -__align;
- const auto __diff = __aligned - __intptr;
- if ((__size + __diff) > __space) {
- return nullptr;
- } else {
- __space -= __diff;
- return __ptr = reinterpret_cast<void*>(__aligned);
- }
-}
-
-template<Architecture A, typename T>
-T* AllocateAlignedMemory(
- T** storage,
- std::size_t size,
- std::size_t alignment) {
- *storage = new T[size + alignment - 1];
- void* ptr = static_cast<void*>(*storage);
- std::size_t storage_size = (size + alignment - 1) * sizeof(T);
- return static_cast<T*>(align(alignment, size * sizeof(T), ptr, storage_size));
-}
-
template<Architecture A, typename T>
struct InstructionSet;
@@ -88,6 +60,9 @@ template<Architecture A>
struct InstructionSet<A, std::int16_t> {
using type = std::int16_t;
static constexpr std::uint32_t kNumVar = kRegisterSize / (8 * sizeof(type));
+ struct alignas(kRegisterSize / 8) Storage {
+ type arr[kNumVar];
+ };
static constexpr std::uint32_t kLogNumVar = 4;
static constexpr std::uint32_t kLSS = 2; // Left Shift Size
static constexpr std::uint32_t kRSS = 30; // Right Shift Size
@@ -121,6 +96,9 @@ template<Architecture A>
struct InstructionSet<A, std::int32_t> {
using type = std::int32_t;
static constexpr std::uint32_t kNumVar = kRegisterSize / (8 * sizeof(type));
+ struct alignas(kRegisterSize / 8) Storage {
+ type arr[kNumVar];
+ };
static constexpr std::uint32_t kLogNumVar = 3;
static constexpr std::uint32_t kLSS = 4;
static constexpr std::uint32_t kRSS = 28;
@@ -176,6 +154,9 @@ template<Architecture A>
struct InstructionSet<A, std::int16_t> {
using type = std::int16_t;
static constexpr std::uint32_t kNumVar = kRegisterSize / (8 * sizeof(type));
+ struct alignas(kRegisterSize / 8) Storage {
+ type arr[kNumVar];
+ };
static constexpr std::uint32_t kLogNumVar = 3;
static constexpr std::uint32_t kLSS = 2;
static constexpr std::uint32_t kRSS = 14;
@@ -208,6 +189,9 @@ template<Architecture A>
struct InstructionSet<A, std::int32_t> {
using type = std::int32_t;
static constexpr std::uint32_t kNumVar = kRegisterSize / (8 * sizeof(type));
+ struct alignas(kRegisterSize / 8) Storage {
+ type arr[kNumVar];
+ };
static constexpr std::uint32_t kLogNumVar = 2;
static constexpr std::uint32_t kLSS = 4;
static constexpr std::uint32_t kRSS = 12;
@@ -239,6 +223,10 @@ struct InstructionSet<A, std::int32_t> {
#if defined(__AVX2__) || defined(__SSE4_1__) || defined(SPOA_USE_SIMDE)
+struct Storage {
+ __mxxxi val;
+};
+
template<Architecture A, typename T>
void _mmxxx_print(const __mxxxi& a) {
__attribute__((aligned(kRegisterSize / 8))) typename T::type unpacked[T::kNumVar]; // NOLINT
@@ -320,45 +308,38 @@ struct SimdAlignmentEngine<A>::Implementation {
#if defined(__AVX2__) || defined(__SSE4_1__) || defined(SPOA_USE_SIMDE)
std::vector<std::uint32_t> node_id_to_rank;
- std::unique_ptr<__mxxxi[]> sequence_profile_storage;
- std::uint64_t sequence_profile_size;
+ std::vector<Storage> sequence_profile_storage;
__mxxxi* sequence_profile;
std::vector<std::int32_t> first_column;
- std::unique_ptr<__mxxxi[]> M_storage;
- std::uint64_t M_size;
+
+ std::vector<Storage> M_storage;
__mxxxi* H;
__mxxxi* F;
__mxxxi* E;
__mxxxi* O;
__mxxxi* Q;
- std::unique_ptr<__mxxxi[]> masks_storage;
- std::uint32_t masks_size;
+ std::vector<Storage> masks_storage;
__mxxxi* masks;
- std::unique_ptr<__mxxxi[]> penalties_storage;
- std::uint32_t penalties_size;
+ std::vector<Storage> penalties_storage;
__mxxxi* penalties;
Implementation()
: node_id_to_rank(),
- sequence_profile_storage(nullptr),
- sequence_profile_size(0),
+ sequence_profile_storage(),
sequence_profile(nullptr),
first_column(),
- M_storage(nullptr),
- M_size(0),
+ M_storage(),
H(nullptr),
F(nullptr),
E(nullptr),
O(nullptr),
Q(nullptr),
- masks_storage(nullptr),
- masks_size(0),
+ masks_storage(),
masks(nullptr),
- penalties_storage(nullptr),
- penalties_size(0),
+ penalties_storage(),
penalties(nullptr) {
}
#endif
@@ -430,84 +411,48 @@ void SimdAlignmentEngine<A>::Realloc(
if (pimpl_->node_id_to_rank.size() < matrix_height - 1) {
pimpl_->node_id_to_rank.resize(matrix_height - 1, 0);
}
- if (pimpl_->sequence_profile_size < num_codes * matrix_width) {
- __mxxxi* storage = nullptr;
- pimpl_->sequence_profile_size = num_codes * matrix_width;
- pimpl_->sequence_profile = AllocateAlignedMemory<A>(
- &storage,
- pimpl_->sequence_profile_size,
- kRegisterSize / 8);
- pimpl_->sequence_profile_storage.reset();
- pimpl_->sequence_profile_storage = std::unique_ptr<__mxxxi[]>(storage);
+ if (pimpl_->sequence_profile_storage.size() < num_codes * matrix_width) {
+ pimpl_->sequence_profile_storage.resize(num_codes * matrix_width);
+ pimpl_->sequence_profile = reinterpret_cast<__mxxxi*>(pimpl_->sequence_profile_storage.data());
}
if (subtype_ == AlignmentSubtype::kLinear) {
if (pimpl_->first_column.size() < matrix_height) {
pimpl_->first_column.resize(matrix_height, 0);
}
- if (pimpl_->M_size < matrix_height * matrix_width) {
- __mxxxi* storage = nullptr;
- pimpl_->M_size = matrix_height * matrix_width;
- pimpl_->H = AllocateAlignedMemory<A>(
- &storage,
- pimpl_->M_size,
- kRegisterSize / 8);
- pimpl_->M_storage.reset();
- pimpl_->M_storage = std::unique_ptr<__mxxxi[]>(storage);
+ if (pimpl_->M_storage.size() < matrix_height * matrix_width) {
+ pimpl_->M_storage.resize(matrix_height * matrix_width);
+ pimpl_->H = reinterpret_cast<__mxxxi*>(pimpl_->M_storage.data());
}
} else if (subtype_ == AlignmentSubtype::kAffine) {
if (pimpl_->first_column.size() < 2 * matrix_height) {
pimpl_->first_column.resize(2 * matrix_height, 0);
}
- if (pimpl_->M_size < 3 * matrix_height * matrix_width) {
- __mxxxi* storage = nullptr;
- pimpl_->M_size = 3 * matrix_height * matrix_width;
- pimpl_->H = AllocateAlignedMemory<A>(
- &storage,
- pimpl_->M_size,
- kRegisterSize / 8);
+ if (pimpl_->M_storage.size() < 3 * matrix_height * matrix_width) {
+ pimpl_->M_storage.resize(3 * matrix_height * matrix_width);
+ pimpl_->H = reinterpret_cast<__mxxxi*>(pimpl_->M_storage.data());
pimpl_->F = pimpl_->H + matrix_height * matrix_width;
pimpl_->E = pimpl_->F + matrix_height * matrix_width;
- pimpl_->M_storage.reset();
- pimpl_->M_storage = std::unique_ptr<__mxxxi[]>(storage);
}
} else if (subtype_ == AlignmentSubtype::kConvex) {
if (pimpl_->first_column.size() < 3 * matrix_height) {
pimpl_->first_column.resize(3 * matrix_height, 0);
}
- if (pimpl_->M_size < 5 * matrix_height * matrix_width) {
- __mxxxi* storage = nullptr;
- pimpl_->M_size = 5 * matrix_height * matrix_width;
- pimpl_->H = AllocateAlignedMemory<A>(
- &storage,
- pimpl_->M_size,
- kRegisterSize / 8);
+ if (pimpl_->M_storage.size() < 5 * matrix_height * matrix_width) {
+ pimpl_->M_storage.resize(5 * matrix_height * matrix_width);
+ pimpl_->H = reinterpret_cast<__mxxxi*>(pimpl_->M_storage.data());
pimpl_->F = pimpl_->H + matrix_height * matrix_width;
pimpl_->E = pimpl_->F + matrix_height * matrix_width;
pimpl_->O = pimpl_->E + matrix_height * matrix_width;
pimpl_->Q = pimpl_->O + matrix_height * matrix_width;
- pimpl_->M_storage.reset();
- pimpl_->M_storage = std::unique_ptr<__mxxxi[]>(storage);
}
}
- if (pimpl_->masks_size < InstructionSet<A, std::int16_t>::kLogNumVar + 1) {
- __mxxxi* storage = nullptr;
- pimpl_->masks_size = InstructionSet<A, std::int16_t>::kLogNumVar + 1;
- pimpl_->masks = AllocateAlignedMemory<A>(
- &storage,
- pimpl_->masks_size,
- kRegisterSize / 8);
- pimpl_->masks_storage.reset();
- pimpl_->masks_storage = std::unique_ptr<__mxxxi[]>(storage);
- }
- if (pimpl_->penalties_size < 2 * InstructionSet<A, std::int16_t>::kLogNumVar) { // NOLINT
- __mxxxi* storage = nullptr;
- pimpl_->penalties_size = 2 * InstructionSet<A, std::int16_t>::kLogNumVar;
- pimpl_->penalties = AllocateAlignedMemory<A>(
- &storage,
- pimpl_->penalties_size,
- kRegisterSize / 8);
- pimpl_->penalties_storage.reset();
- pimpl_->penalties_storage = std::unique_ptr<__mxxxi[]>(storage);
+ if (pimpl_->masks_storage.size() < InstructionSet<A, std::int16_t>::kLogNumVar + 1) {
+ pimpl_->masks_storage.resize(InstructionSet<A, std::int16_t>::kLogNumVar + 1);
+ pimpl_->masks = reinterpret_cast<__mxxxi*>(pimpl_->masks_storage.data());
+ }
+ if (pimpl_->penalties_storage.size() < 2 * InstructionSet<A, std::int16_t>::kLogNumVar) { // NOLINT
+ pimpl_->penalties_storage.resize(2 * InstructionSet<A, std::int16_t>::kLogNumVar);
+ pimpl_->penalties = reinterpret_cast<__mxxxi*>(pimpl_->penalties_storage.data());
}
#endif
(void) matrix_width;
@@ -960,11 +905,8 @@ Alignment SimdAlignmentEngine<A>::Linear(
static_cast<std::uint32_t>(rank_to_node[i]->inedges.size()));
}
- typename T::type* backtrack_storage = nullptr;
- typename T::type* H = AllocateAlignedMemory<A>(
- &backtrack_storage,
- 3 * T::kNumVar + 2 * T::kNumVar * max_num_predecessors,
- kRegisterSize / 8);
+ std::vector<typename T::Storage> backtrack_storage(3 * T::kNumVar + 2 * T::kNumVar * max_num_predecessors);
+ typename T::type* H = reinterpret_cast<typename T::type*>(backtrack_storage.data());
typename T::type* H_pred = H + T::kNumVar;
typename T::type* H_diag_pred = H_pred + T::kNumVar * max_num_predecessors;
typename T::type* H_left_pred = H_diag_pred + T::kNumVar * max_num_predecessors; // NOLINT
@@ -1097,8 +1039,6 @@ Alignment SimdAlignmentEngine<A>::Linear(
j_mod = j % T::kNumVar;
} while (true);
- delete[] backtrack_storage;
-
// update alignment for NW (backtrack stops on first row or column)
if (type_ == AlignmentType::kNW) {
while (i == 0 && j != -1) {
@@ -1329,11 +1269,8 @@ Alignment SimdAlignmentEngine<A>::Affine(
static_cast<std::uint32_t>(rank_to_node[i]->inedges.size()));
}
- typename T::type* backtrack_storage = nullptr;
- typename T::type* H = AllocateAlignedMemory<A>(
- &backtrack_storage,
- 6 * T::kNumVar + 3 * T::kNumVar * max_num_predecessors,
- kRegisterSize / 8);
+ std::vector<typename T::Storage> backtrack_storage(6 * T::kNumVar + 3 * T::kNumVar * max_num_predecessors);
+ typename T::type* H = reinterpret_cast<typename T::type*>(backtrack_storage.data());
typename T::type* H_pred = H + T::kNumVar;
typename T::type* H_diag_pred = H_pred + T::kNumVar * max_num_predecessors;
typename T::type* H_left = H_diag_pred + T::kNumVar * max_num_predecessors;
@@ -1547,8 +1484,6 @@ Alignment SimdAlignmentEngine<A>::Affine(
}
} while (true);
- delete[] backtrack_storage;
-
// update alignment for NW (backtrack stops on first row or column)
if (type_ == AlignmentType::kNW) {
while (i == 0 && j != -1) {
@@ -1831,11 +1766,8 @@ Alignment SimdAlignmentEngine<A>::Convex(
static_cast<std::uint32_t>(rank_to_node[i]->inedges.size()));
}
- typename T::type* backtrack_storage = nullptr;
- typename T::type* H = AllocateAlignedMemory<A>(
- &backtrack_storage,
- 9 * T::kNumVar + 4 * T::kNumVar * max_num_predecessors,
- kRegisterSize / 8);
+ std::vector<typename T::Storage> backtrack_storage(9 * T::kNumVar + 4 * T::kNumVar * max_num_predecessors);
+ typename T::type* H = reinterpret_cast<typename T::type*>(backtrack_storage.data());
typename T::type* H_pred = H + T::kNumVar;
typename T::type* H_diag_pred = H_pred + T::kNumVar * max_num_predecessors;
typename T::type* H_left = H_diag_pred + T::kNumVar * max_num_predecessors;
@@ -2093,8 +2025,6 @@ Alignment SimdAlignmentEngine<A>::Convex(
}
} while (true);
- delete[] backtrack_storage;
-
// update alignment for NW (backtrack stops on first row or column)
if (type_ == AlignmentType::kNW) {
while (i == 0 && j != -1) {
=====================================
src/spoa_config.h.in
=====================================
@@ -0,0 +1,12 @@
+// Copyright (c) 2023 Robert Vaser
+
+#ifndef SPOA_CONFIG_H_
+#define SPOA_CONFIG_H_
+
+namespace spoa {
+
+constexpr char SPOA_VERSION[] = "@SPOA_VERSION@";
+
+} // namespace spoa
+
+#endif // SPOA_CONFIG_H_
=====================================
src/version.cpp
=====================================
@@ -0,0 +1,13 @@
+// Copyright (c) 2023 Robert Vaser
+
+#include "spoa/version.hpp"
+
+#include "spoa_config.h"
+
+namespace spoa {
+
+std::string Version() {
+ return std::string(SPOA_VERSION);
+}
+
+} // namespace spoa
=====================================
subprojects/bioparser.wrap
=====================================
@@ -0,0 +1,5 @@
+[wrap-git]
+directory = bioparser
+
+url = https://github.com/rvaser/bioparser
+revision = 3.1.0
=====================================
subprojects/biosoup.wrap
=====================================
@@ -0,0 +1,5 @@
+[wrap-git]
+directory = biosoup
+
+url = https://github.com/rvaser/biosoup
+revision = 0.11.0
=====================================
subprojects/cereal.wrap
=====================================
@@ -0,0 +1,15 @@
+[wrap-file]
+directory = cereal-1.3.0
+
+source_url = https://github.com/USCiLab/cereal/archive/v1.3.0.tar.gz
+source_filename = cereal-1.3.0.tar.gz
+source_hash = 329ea3e3130b026c03a4acc50e168e7daff4e6e661bc6a7dfec0d77b570851d5
+
+patch_url = https://wrapdb.mesonbuild.com/v2/cereal_1.3.0-1/get_patch
+patch_filename = cereal-1.3.0-1-wrap.zip
+patch_hash = 418724e544fb7cf2eab4b0dbd623925f81e79e7b38f098f6dc07bf2c27cb48a6
+
+wrapdb_version = 1.3.0-1
+
+[provide]
+cereal = cereal_dep
=====================================
subprojects/gtest.wrap
=====================================
@@ -0,0 +1,16 @@
+[wrap-file]
+directory = googletest-release-1.10.0
+
+source_url = https://github.com/google/googletest/archive/release-1.10.0.zip
+source_filename = gtest-1.10.0.zip
+source_hash = 94c634d499558a76fa649edb13721dce6e98fb1e7018dfaeba3cd7a083945e91
+
+patch_url = https://wrapdb.mesonbuild.com/v2/gtest_1.10.0-1/get_patch
+patch_filename = gtest-1.10.0-1-wrap.zip
+patch_hash = 04ff14e8880e4e465f6260221e9dfd56fea6bc7cce4c4aff0dc528e4a2c8f514
+
+wrapdb_version = 1.10.0-1
+
+[provide]
+gtest = gtest_dep
+gtest_main = gtest_main_dep
=====================================
subprojects/simde.wrap
=====================================
@@ -0,0 +1,9 @@
+[wrap-file]
+directory = simde-0.7.6
+
+source_url = https://github.com/simd-everywhere/simde/archive/refs/tags/v0.7.6.zip
+source_filename = simde-0.7.6.zip
+source_hash = ed05e7d6f94c7c1c4ee6aa60f829c3a943a046f45061a3d291c63bbd4f89e5bb
+
+[provide]
+simde = simde_dep
=====================================
test/meson.build
=====================================
@@ -0,0 +1,31 @@
+spoa_test_config = configuration_data()
+spoa_test_config.set('SPOA_TEST_DATA', meson.project_source_root() + '/test/data/sample.fastq.gz')
+
+###########
+# Sources #
+###########
+
+spoa_test_config_headers = [
+ configure_file(
+ input : 'spoa_test_config.h.in',
+ output : 'spoa_test_config.h',
+ configuration : spoa_test_config)
+]
+
+spoa_test_sources = files([
+ 'spoa_test.cpp',
+]) + spoa_test_config_headers
+
+spoa_test = executable(
+ 'spoa_test',
+ spoa_test_sources,
+ dependencies : [spoa_lib_deps, spoa_biosoup_dep, spoa_bioparser_dep, spoa_gtest_dep],
+ include_directories : spoa_include_directories,
+ link_with : spoa_lib,
+ install : false)
+
+#########
+# Tests #
+#########
+
+test('spoa gtest unit tests', spoa_test)
=====================================
test/spoa_test.cpp
=====================================
@@ -11,6 +11,8 @@
#include "spoa/spoa.hpp"
+#include "spoa_test_config.h"
+
std::atomic<std::uint32_t> biosoup::Sequence::num_objects{0};
namespace spoa {
@@ -18,7 +20,7 @@ namespace test {
class SpoaTest: public ::testing::Test {
public:
- void Setup(
+ void Initialize(
AlignmentType type,
std::int8_t m,
std::int8_t n,
@@ -27,7 +29,7 @@ class SpoaTest: public ::testing::Test {
std::int8_t q,
std::int8_t c,
bool quality) {
- auto p = bioparser::Parser<biosoup::Sequence>::Create<bioparser::FastqParser>(TEST_DATA); // NOLINT
+ auto p = bioparser::Parser<biosoup::Sequence>::Create<bioparser::FastqParser>(SPOA_TEST_DATA); // NOLINT
s = p->Parse(-1);
EXPECT_EQ(55, s.size());
@@ -109,17 +111,10 @@ TEST(SpoaAlignmentTest, LargeInput) {
std::string(exception.what()).substr(11),
"AlignmentEngine::Prealloc] error: too large sequence!");
}
- try {
- ae->Prealloc((1ULL << 31) - 1, -1);
- } catch (std::invalid_argument& exception) {
- EXPECT_EQ(
- std::string(exception.what()).substr(11),
- "AlignmentEngine::Prealloc] error: insufficient memory!");
- }
}
TEST_F(SpoaTest, Clear) {
- Setup(AlignmentType::kSW, 5, -4, -8, -8, -8, -8, false);
+ Initialize(AlignmentType::kSW, 5, -4, -8, -8, -8, -8, false);
Align();
auto c = gr.GenerateConsensus();
@@ -130,7 +125,7 @@ TEST_F(SpoaTest, Clear) {
#ifdef SPOA_USE_CEREAL
TEST_F(SpoaTest, Archive) {
- Setup(AlignmentType::kNW, 2, -5, -2, -2, -2, -2, true);
+ Initialize(AlignmentType::kNW, 2, -5, -2, -2, -2, -2, true);
{
std::ofstream os("spoa.test.cereal");
@@ -152,7 +147,7 @@ TEST_F(SpoaTest, Archive) {
#endif
TEST_F(SpoaTest, Local) {
- Setup(AlignmentType::kSW, 5, -4, -8, -8, -8, -8, false);
+ Initialize(AlignmentType::kSW, 5, -4, -8, -8, -8, -8, false);
Align();
std::string c =
@@ -168,7 +163,7 @@ TEST_F(SpoaTest, Local) {
}
TEST_F(SpoaTest, LocalAffine) {
- Setup(AlignmentType::kSW, 5, -4, -8, -6, -8, -6, false);
+ Initialize(AlignmentType::kSW, 5, -4, -8, -6, -8, -6, false);
Align();
std::string c =
@@ -184,7 +179,7 @@ TEST_F(SpoaTest, LocalAffine) {
}
TEST_F(SpoaTest, LocalConvex) {
- Setup(AlignmentType::kSW, 5, -4, -8, -6, -10, -2, false);
+ Initialize(AlignmentType::kSW, 5, -4, -8, -6, -10, -2, false);
Align();
std::string c =
@@ -200,7 +195,7 @@ TEST_F(SpoaTest, LocalConvex) {
}
TEST_F(SpoaTest, LocalWithQualities) {
- Setup(AlignmentType::kSW, 5, -4, -8, -8, -8, -8, true);
+ Initialize(AlignmentType::kSW, 5, -4, -8, -8, -8, -8, true);
Align();
std::string c =
@@ -216,7 +211,7 @@ TEST_F(SpoaTest, LocalWithQualities) {
}
TEST_F(SpoaTest, LocalAffineWithQualities) {
- Setup(AlignmentType::kSW, 5, -4, -8, -6, -8, -6, true);
+ Initialize(AlignmentType::kSW, 5, -4, -8, -6, -8, -6, true);
Align();
std::string c =
@@ -232,7 +227,7 @@ TEST_F(SpoaTest, LocalAffineWithQualities) {
}
TEST_F(SpoaTest, LocalConvexWithQualities) {
- Setup(AlignmentType::kSW, 5, -4, -8, -6, -10, -2, true);
+ Initialize(AlignmentType::kSW, 5, -4, -8, -6, -10, -2, true);
Align();
std::string c =
@@ -248,7 +243,7 @@ TEST_F(SpoaTest, LocalConvexWithQualities) {
}
TEST_F(SpoaTest, Global) {
- Setup(AlignmentType::kNW, 5, -4, -8, -8, -8, -8, false);
+ Initialize(AlignmentType::kNW, 5, -4, -8, -8, -8, -8, false);
Align();
std::string c =
@@ -264,7 +259,7 @@ TEST_F(SpoaTest, Global) {
}
TEST_F(SpoaTest, GlobalAffine) {
- Setup(AlignmentType::kNW, 5, -4, -8, -6, -8, -6, false);
+ Initialize(AlignmentType::kNW, 5, -4, -8, -6, -8, -6, false);
Align();
std::string c =
@@ -280,7 +275,7 @@ TEST_F(SpoaTest, GlobalAffine) {
}
TEST_F(SpoaTest, GlobalConvex) {
- Setup(AlignmentType::kNW, 5, -4, -8, -6, -10, -2, false);
+ Initialize(AlignmentType::kNW, 5, -4, -8, -6, -10, -2, false);
Align();
std::string c =
@@ -296,7 +291,7 @@ TEST_F(SpoaTest, GlobalConvex) {
}
TEST_F(SpoaTest, GlobalWithQualities) {
- Setup(AlignmentType::kNW, 5, -4, -8, -8, -8, -8, true);
+ Initialize(AlignmentType::kNW, 5, -4, -8, -8, -8, -8, true);
Align();
std::string c =
@@ -312,7 +307,7 @@ TEST_F(SpoaTest, GlobalWithQualities) {
}
TEST_F(SpoaTest, GlobalAffineWithQualities) {
- Setup(AlignmentType::kNW, 5, -4, -8, -6, -8, -6, true);
+ Initialize(AlignmentType::kNW, 5, -4, -8, -6, -8, -6, true);
Align();
std::string c =
@@ -328,7 +323,7 @@ TEST_F(SpoaTest, GlobalAffineWithQualities) {
}
TEST_F(SpoaTest, GlobalConvexWithQualities) {
- Setup(AlignmentType::kNW, 5, -4, -8, -6, -10, -2, true);
+ Initialize(AlignmentType::kNW, 5, -4, -8, -6, -10, -2, true);
Align();
std::string c =
@@ -344,7 +339,7 @@ TEST_F(SpoaTest, GlobalConvexWithQualities) {
}
TEST_F(SpoaTest, SemiGlobal) {
- Setup(AlignmentType::kOV, 5, -4, -8, -8, -8, -8, false);
+ Initialize(AlignmentType::kOV, 5, -4, -8, -8, -8, -8, false);
Align();
std::string c =
@@ -360,7 +355,7 @@ TEST_F(SpoaTest, SemiGlobal) {
}
TEST_F(SpoaTest, SemiGlobalAffine) {
- Setup(AlignmentType::kOV, 5, -4, -8, -6, -8, -6, false);
+ Initialize(AlignmentType::kOV, 5, -4, -8, -6, -8, -6, false);
Align();
std::string c =
@@ -376,7 +371,7 @@ TEST_F(SpoaTest, SemiGlobalAffine) {
}
TEST_F(SpoaTest, SemiGlobalConvex) {
- Setup(AlignmentType::kOV, 5, -4, -8, -6, -10, -2, false);
+ Initialize(AlignmentType::kOV, 5, -4, -8, -6, -10, -2, false);
Align();
std::string c =
@@ -392,7 +387,7 @@ TEST_F(SpoaTest, SemiGlobalConvex) {
}
TEST_F(SpoaTest, SemiGlobalWithQualities) {
- Setup(AlignmentType::kOV, 5, -4, -8, -8, -8, -8, true);
+ Initialize(AlignmentType::kOV, 5, -4, -8, -8, -8, -8, true);
Align();
std::string c =
@@ -408,7 +403,7 @@ TEST_F(SpoaTest, SemiGlobalWithQualities) {
}
TEST_F(SpoaTest, SemiGlobalAffineWithQualities) {
- Setup(AlignmentType::kOV, 5, -4, -8, -6, -8, -6, true);
+ Initialize(AlignmentType::kOV, 5, -4, -8, -6, -8, -6, true);
Align();
std::string c =
@@ -424,7 +419,7 @@ TEST_F(SpoaTest, SemiGlobalAffineWithQualities) {
}
TEST_F(SpoaTest, SemiGlobalConvexWithQualities) {
- Setup(AlignmentType::kOV, 5, -4, -8, -6, -10, -2, true);
+ Initialize(AlignmentType::kOV, 5, -4, -8, -6, -10, -2, true);
Align();
std::string c =
=====================================
test/spoa_test_config.h.in
=====================================
@@ -0,0 +1,14 @@
+// Copyright (c) 2023 Robert Vaser
+
+#ifndef SPOA_TEST_CONFIG_H_
+#define SPOA_TEST_CONFIG_H_
+
+namespace spoa {
+namespace test {
+
+constexpr char SPOA_TEST_DATA[] = "@SPOA_TEST_DATA@";
+
+} // namespace test
+} // namespace spoa
+
+#endif // SPOA_TEST_CONFIG_H_
View it on GitLab: https://salsa.debian.org/med-team/spoa/-/commit/ccf4f10523a198e6f5a341e4050d59b45d6738d7
--
View it on GitLab: https://salsa.debian.org/med-team/spoa/-/commit/ccf4f10523a198e6f5a341e4050d59b45d6738d7
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20240321/34c219de/attachment-0001.htm>
More information about the debian-med-commit
mailing list