From adf9859d5c0163a4b4e00ea483dadb59084e3b1e Mon Sep 17 00:00:00 2001 From: Hannes Hauswedell Date: Wed, 21 Sep 2022 19:04:15 +0000 Subject: [PATCH 1/4] [fix] view madness in seqan2 --- src/holder_tristate_overload.h | 224 +++++++++++++++++++++++++++++++++ src/seqan2seqan3.hpp | 20 +++ 2 files changed, 244 insertions(+) create mode 100644 src/holder_tristate_overload.h diff --git a/src/holder_tristate_overload.h b/src/holder_tristate_overload.h new file mode 100644 index 000000000..ba4f557bb --- /dev/null +++ b/src/holder_tristate_overload.h @@ -0,0 +1,224 @@ +// ========================================================================== +// SeqAn - The Library for Sequence Analysis +// ========================================================================== +// Copyright (c) 2006-2018, Knut Reinert, FU Berlin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Knut Reinert or the FU Berlin nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +// +// ========================================================================== +// Author: Andreas Gogol-Döring +// ========================================================================== +// Tristate Holder Implementation. +// ========================================================================== + +#pragma once + +#include + +using overload_t = std::ranges::take_view>>>>; + +template +concept overload_c = std::same_as, overload_t>; + +namespace seqan +{ + +// ============================================================================ +// Tags, Classes, Enums +// ============================================================================ +template +struct Holder +{ + enum EHolderState + { + EMPTY = 0, + OWNER = 1, + DEPENDENT = 2 + }; + + typedef std::optional THostValue; + + // ------------------------------------------------------------------------ + // Members + // ------------------------------------------------------------------------ + + THostValue data_value; + EHolderState data_state; + + // ------------------------------------------------------------------------ + // Constructors; Destructor + // ------------------------------------------------------------------------ + + Holder() : data_value{}, data_state(EMPTY) + { + } + + Holder(Holder const & source_) : data_value{}, data_state(EMPTY) + { + data_value = source_; + } + + explicit + Holder(THostValue & value_) : data_value{}, data_state(EMPTY) + { + data_value = value_; + } + + explicit + Holder(THostValue const & value_) : data_value{}, data_state(EMPTY) + { + data_value = value_; + } + + ~Holder() + { + clear(*this); + } + + // ------------------------------------------------------------------------ + // Assignment Operators; Must be defined in class. + // ------------------------------------------------------------------------ + + Holder & operator=(Holder const &) = default; + + Holder & operator=(THostValue const & value_) + { + data_value = value_; + return *this; + } + + // ------------------------------------------------------------------------ + // Conversion Operators; Must be defined in class. + // ------------------------------------------------------------------------ + + inline operator THostValue() + { + return data_value; + } +}; + +// ============================================================================ +// Functions +// ============================================================================ + +/// ---------------------------------------------------------------------------- +// Function clear() +// ---------------------------------------------------------------------------- + +template +inline void +clear(Holder & me) +{ + me.data_value.reset(); + me.data_state = Holder::EMPTY; +} + +// ---------------------------------------------------------------------------- +// Function setValue() +// ---------------------------------------------------------------------------- + +template +inline void +setValue(Holder & me, + TValue const & value_) +{ + me.data_value = value_; + me.data_state = Holder::OWNER; +} + +template +inline void +setValue(Holder & me, + TValue const & value_) +{ + me.data_value = value_; + me.data_state = Holder::OWNER; +} + +// ---------------------------------------------------------------------------- +// Function value() +// ---------------------------------------------------------------------------- + +template +auto & value(Holder & me) +{ + SEQAN_ASSERT_NOT(empty(me)); // HERE BE DRAGONS!!! + return * me.data_value; +} + +template +auto & value(Holder const & me) +{ + SEQAN_ASSERT_NOT(empty(me)); + + return * me.data_value; +} + +// ---------------------------------------------------------------------------- +// Function assignValue() +// ---------------------------------------------------------------------------- + +template +inline void +assignValue(Holder & me, + TSource const & value_) +{ + setValue(me, value_); +} + +// ---------------------------------------------------------------------------- +// Function moveValue() +// ---------------------------------------------------------------------------- + +template +inline void +moveValue(Holder & me, + TSource const & value_) +{ + setValue(me, value_); +} + +// ---------------------------------------------------------------------------- +// Function assign() +// ---------------------------------------------------------------------------- + +template +inline void +assign(Holder & target_, + Holder const & source_) +{ + target_ = source_; +} + +template +inline void +assign(Holder & target_, + Holder const & source_) +{ + target_ = source_; +} + +} // namespace seqan diff --git a/src/seqan2seqan3.hpp b/src/seqan2seqan3.hpp index 32b09212d..665ec34bb 100644 --- a/src/seqan2seqan3.hpp +++ b/src/seqan2seqan3.hpp @@ -57,6 +57,7 @@ inline seqan3::gapped gapValueImpl(seqan3::gapped const *) #include #include +#include "holder_tristate_overload.h" #include "bisulfite_scoring.hpp" namespace seqan @@ -214,6 +215,25 @@ struct GetValue> using Type = std::ranges::range_reference_t; }; +template +decltype(auto) source(Gaps const & gaps) +{ + return value(gaps._source); +} + +template +decltype(auto) source(Gaps & gaps) +{ + return value(gaps._source); +} + +template +inline void assignSource(Gaps & gaps, TSequence const & source) +{ + setValue(gaps._source, source); + _reinitArrayGaps(gaps); +} + // –--------------------------------------------------------------------------- // range stuff // –--------------------------------------------------------------------------- From 62e46ce67845ad3245d5d5cec622df6f3bce41b9 Mon Sep 17 00:00:00 2001 From: Hannes Hauswedell Date: Thu, 22 Sep 2022 14:10:37 +0000 Subject: [PATCH 2/4] [test] add gcc12 to CI --- .github/workflows/ci_linux.yml | 6 ++++++ .github/workflows/ci_macos.yml | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci_linux.yml b/.github/workflows/ci_linux.yml index de74d5704..134d3e836 100644 --- a/.github/workflows/ci_linux.yml +++ b/.github/workflows/ci_linux.yml @@ -21,6 +21,12 @@ jobs: fail-fast: false matrix: include: + - name: "gcc12" + install: "g++-12" + cxx: "g++-12" + cc: "gcc-12" + build_type: Release + - name: "gcc11" install: "g++-11" cxx: "g++-11" diff --git a/.github/workflows/ci_macos.yml b/.github/workflows/ci_macos.yml index 88f924f31..cfec49d6d 100644 --- a/.github/workflows/ci_macos.yml +++ b/.github/workflows/ci_macos.yml @@ -22,9 +22,9 @@ jobs: fail-fast: false matrix: include: - - name: "gcc11" - cxx: "g++-11" - cc: "gcc-11" + - name: "gcc12" + cxx: "g++-12" + cc: "gcc-12" build_type: Release - name: "gcc10" From a7e26f10b2f000b6f61bdf20d40f0d297e27149b Mon Sep 17 00:00:00 2001 From: Hannes Hauswedell Date: Thu, 22 Sep 2022 14:46:29 +0000 Subject: [PATCH 3/4] [infra] fix default builds without native --- .github/workflows/ci_linux.yml | 2 +- .github/workflows/ci_macos.yml | 2 +- src/CMakeLists.txt | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_linux.yml b/.github/workflows/ci_linux.yml index 134d3e836..d5a778f8e 100644 --- a/.github/workflows/ci_linux.yml +++ b/.github/workflows/ci_linux.yml @@ -94,7 +94,7 @@ jobs: run: | mkdir build cd build - cmake ../lambda -DLAMBDA_COMPILE_THREADS=2 -DLAMBDA_NATIVE_BUILD=ON -DCMAKE_CXX_FLAGS="${{ matrix.cxx_flags }}" -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache + cmake ../lambda -DLAMBDA_COMPILE_THREADS=2 -DLAMBDA_NATIVE_BUILD=OFF -DCMAKE_CXX_FLAGS="${{ matrix.cxx_flags }}" -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache - name: Build tests if: matrix.name != 'clang_format' diff --git a/.github/workflows/ci_macos.yml b/.github/workflows/ci_macos.yml index cfec49d6d..51e8528ce 100644 --- a/.github/workflows/ci_macos.yml +++ b/.github/workflows/ci_macos.yml @@ -75,7 +75,7 @@ jobs: run: | mkdir build cd build - cmake ../lambda -DLAMBDA_COMPILE_THREADS=3 -DLAMBDA_NATIVE_BUILD=ON -DCMAKE_CXX_FLAGS="${{ matrix.cxx_flags }}" -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache + cmake ../lambda -DLAMBDA_COMPILE_THREADS=3 -DLAMBDA_NATIVE_BUILD=OFF -DCMAKE_CXX_FLAGS="${{ matrix.cxx_flags }}" -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache - name: Build tests env: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 491c61ba4..9baae0502 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -40,6 +40,8 @@ if (LAMBDA_NATIVE_BUILD) if (CMAKE_CXX_COMPILER_ID MATCHES "Intel") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -xHOST -ipo -no-prec-div -fp-model fast=2") endif (CMAKE_CXX_COMPILER_ID MATCHES "Intel") +else (LAMBDA_NATIVE_BUILD) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmmx -msse -msse2 -msse3 -mssse3 -msse4 -mpopcnt") endif (LAMBDA_NATIVE_BUILD) if (LAMBDA_STATIC_BUILD) From c68dabf27c9f3b919096c4fa7209b7c112a1931c Mon Sep 17 00:00:00 2001 From: Hannes Hauswedell Date: Thu, 22 Sep 2022 17:15:00 +0000 Subject: [PATCH 4/4] [fix,test] check return values of system() calls in tests --- test/cli/index_test.cpp | 23 ++++++++++++++++++++--- test/cli/search_test.cpp | 31 ++++++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/test/cli/index_test.cpp b/test/cli/index_test.cpp index eec45f64b..435c22936 100644 --- a/test/cli/index_test.cpp +++ b/test/cli/index_test.cpp @@ -5,6 +5,18 @@ struct index_test : public cli_test { + std::string md5_cmd; + + void determine_md5_cmd() + { + if (std::system("echo foo | md5sum > /dev/null 2>&1") == 0) + md5_cmd = "md5sum"; + else if (std::system("echo foo | md5 > /dev/null 2>&1") == 0) + md5_cmd = "md5"; + + ASSERT_FALSE(md5_cmd.empty()); + } + void run_index_test(std::string const & index_command, std::string const & db_file, std::string const & index_file, @@ -18,10 +30,15 @@ struct index_test : public cli_test "--db-index-type", index_type, "-r", reduction); - EXPECT_EQ(result.exit_code, 0); + ASSERT_EQ(result.exit_code, 0); + + if (md5_cmd.empty()) + determine_md5_cmd(); - std::system(("md5sum " + index_file + " > md5sum_test.txt").c_str()); - std::system(("md5sum " + (std::string) data(control_file) + " > md5sum_control.txt").c_str()); + int ret = std::system((md5_cmd + " " + index_file + " > md5sum_test.txt").c_str()); + ASSERT_TRUE(ret == 0); + ret = std::system((md5_cmd + " " + (std::string) data(control_file) + " > md5sum_control.txt").c_str()); + ASSERT_TRUE(ret == 0); std::ifstream test_output ("md5sum_test.txt"); std::ifstream control_output ("md5sum_control.txt"); diff --git a/test/cli/search_test.cpp b/test/cli/search_test.cpp index 1e3b559ae..3ba870f16 100644 --- a/test/cli/search_test.cpp +++ b/test/cli/search_test.cpp @@ -5,6 +5,18 @@ struct search_test : public cli_test { + std::string md5_cmd; + + void determine_md5_cmd() + { + if (std::system("echo foo | md5sum > /dev/null 2>&1") == 0) + md5_cmd = "md5sum"; + else if (std::system("echo foo | md5 > /dev/null 2>&1") == 0) + md5_cmd = "md5"; + + ASSERT_FALSE(md5_cmd.empty()); + } + void run_search_test(std::string const & index_command, std::string const & db_file, std::string const & index_file, @@ -29,12 +41,19 @@ struct search_test : public cli_test "--version-to-outputfile", "0", "-o", output_file); - EXPECT_EQ(result_search.exit_code, 0); + ASSERT_EQ(result_search.exit_code, 0); + + int ret = 0; if (output_type == "bam") { - std::system(("md5sum " + output_file + " > md5sum_test.txt").c_str()); - std::system(("md5sum " + (std::string) data(control_file) + " > md5sum_control.txt").c_str()); + if (md5_cmd.empty()) + determine_md5_cmd(); + + ret = std::system((md5_cmd + " " + output_file + " > md5sum_test.txt").c_str()); + ASSERT_TRUE(ret == 0); + ret = std::system((md5_cmd + " " + (std::string) data(control_file) + " > md5sum_control.txt").c_str()); + ASSERT_TRUE(ret == 0); std::ifstream test_output ("md5sum_test.txt"); std::ifstream control_output ("md5sum_control.txt"); @@ -56,12 +75,14 @@ struct search_test : public cli_test if (output_type == "m9_gz") { - system(("gunzip " + output_file).c_str()); + ret = system(("gunzip " + output_file).c_str()); + ASSERT_TRUE(ret == 0); test_output.open(output_file.substr(0, output_file.length() - 3)); } else if (output_type == "sam_bz2") { - system(("bzip2 -d " + output_file).c_str()); + ret = system(("bzip2 -d " + output_file).c_str()); + ASSERT_TRUE(ret == 0); test_output.open(output_file.substr(0, output_file.length() - 4)); } else