Skip to content

Commit 895e58b

Browse files
committed
Squashed commit of the following:
commit f2488f431acbc45cd04cc1705fb0e0480f9b2d3f Author: Benjamin Buchfink <buchfink@gmail.com> Date: Tue Jul 22 18:50:02 2025 +0200 Updated version commit 4f3650ed6690bdfd4d4322f80ceb7755159e943e Author: Benjamin Buchfink <buchfink@gmail.com> Date: Tue Jul 22 18:32:18 2025 +0200 Fixed target-indexed bug commit e8cc97fd0df0356074f1e6c802c13f062657b46b Author: Benjamin Buchfink <buchfink@gmail.com> Date: Sun Jul 20 11:31:54 2025 +0200 Updated changelog commit a8b454b4422acf7cc3d917e6e1e9428cdbb5c868 Author: Benjamin Buchfink <buchfink@gmail.com> Date: Thu Jul 10 23:33:05 2025 +0200 Added bidirectional coverage commit 07d2b898299c98f90e5d174567a199db66c222f7 Author: Benjamin Buchfink <buchfink@gmail.com> Date: Fri Jul 4 22:55:44 2025 +0200 Added multiround logic commit 2e3c6cafe5d4700b23f7dcc2bfcdc9a1d0850503 Merge: d832aa36 8ec818c Author: Benjamin Buchfink <buchfink@gmail.com> Date: Mon Jun 30 17:19:04 2025 +0200 Merged w/master
1 parent 8ec818c commit 895e58b

19 files changed

Lines changed: 570 additions & 205 deletions

CMakeLists.txt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,28 @@ include(CheckSymbolExists)
55
include(CheckTypeSize)
66

77
option(BUILD_STATIC "BUILD_STATIC" OFF)
8-
option(EXTRA "EXTRA" OFF)
98
option(STATIC_LIBGCC "STATIC_LIBGCC" OFF)
109
option(STATIC_LIBSTDC++ "STATIC_LIBSTDC++" OFF)
1110
option(X86 "X86" ON)
1211
option(ARM "ARM" OFF)
1312
option(AARCH64 "AARCH64" OFF)
13+
option(WITH_ZSTD "WITH_ZSTD" OFF)
14+
15+
# experimental options not suitable for deployment purposes
16+
option(EXTRA "EXTRA" OFF)
1417
option(STRICT_BAND "STRICT_BAND" ON)
1518
option(LEFTMOST_SEED_FILTER "LEFTMOST_SEED_FILTER" ON)
1619
option(SEQ_MASK "SEQ_MASK" ON)
1720
option(DP_STAT "DP_STAT" OFF)
1821
option(SINGLE_THREADED "SINGLE_THREADED" OFF)
19-
option(WITH_ZSTD "WITH_ZSTD" OFF)
2022
option(HIT_KEEP_TARGET_ID "HIT_KEEP_TARGET_ID" OFF)
2123
option(LONG_SEEDS "LONG_SEEDS" OFF)
2224
option(WITH_AVX512 "WITH_AVX512" OFF)
2325
option(WITH_DNA "WITH_DNA" OFF)
2426
option(WITH_MCL "WITH_MCL" OFF)
2527
option(WITH_MIMALLOC "WITH_MIMALLOC" OFF)
2628
option(USE_TLS "USE_TLS" OFF)
29+
2730
set(MAX_SHAPE_LEN 19)
2831
set(BLAST_INCLUDE_DIR "" CACHE STRING "BLAST_INCLUDE_DIR")
2932
set(BLAST_LIBRARY_DIR "" CACHE STRING "BLAST_LIBRARY_DIR")
@@ -382,6 +385,7 @@ set(OBJECTS
382385
src/cluster/external/external.cpp
383386
src/cluster/external/align.cpp
384387
src/cluster/external/cluster.cpp
388+
src/cluster/external/output.cpp
385389
)
386390

387391
if(WITH_DNA)
@@ -503,7 +507,8 @@ endif()
503507

504508
if (${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
505509
find_library(BCRYPT_LIBRARY BCrypt)
506-
target_link_libraries(diamond ${BCRYPT_LIBRARY})
510+
find_library(WS2_32_LIBRARY Ws2_32)
511+
target_link_libraries(diamond ${BCRYPT_LIBRARY} ${WS2_32_LIBRARY})
507512
endif()
508513

509514
target_link_libraries(diamond ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})

src/ChangeLog

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
1+
[2.1.13]
2+
- Fixed an invalid error message for the `cluster`, `deepclust` and `linclust`
3+
workflows.
4+
- Added the option `--oid-output` to output OIDs instead of accessions for
5+
the clustering workflows, reducing its memory use.
6+
- Added support for using the `--multiprocessing` feature on Windows.
7+
- Using `--multiprocessing` requires explicitly setting `--parallel-tmpdir`.
8+
- Fixed a bug that could cause a crash when the `--target-indexed` option was
9+
used.
10+
- As of now, a macOS binary is available as a GitHub release, supporting both
11+
x86 and Apple silicon CPUs. Using BLAST databases is also supported.
12+
113
[2.1.12]
214
- Added support for the new NCBI taxonomic ranks "cellular root",
315
"acellular root", "domain" and "realm".
16+
- Added support for using BLAST databases to the Bioconda release.
417
- Fixed compiler errors for Clang 20.
518
- Enabled transitive closure computation in earlier clustering rounds and
619
for bi-directional coverage clustering.

src/basic/basic.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
2929
#include "stats/standard_matrix.h"
3030
#include "util/log_stream.h"
3131

32-
const char* Const::version_string = "2.1.12";
32+
const char* Const::version_string = "2.1.13";
3333
using std::string;
3434
using std::vector;
3535
using std::count;

src/basic/config.cpp

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
3737
#include "search/search.h"
3838
#include "stats/cbs.h"
3939
#include "basic/shape.h"
40-
#ifndef _MSC_VER
41-
#include <sys/stat.h>
42-
#endif
4340

4441
using std::thread;
4542
using std::stringstream;
@@ -930,26 +927,15 @@ Config::Config(int argc, const char **argv, bool check_io, CommandLineParser& pa
930927
if (query_range_culling && taxon_k != 0)
931928
throw std::runtime_error("--taxon-k is not supported for --range-culling mode.");
932929

933-
if (parallel_tmpdir == "") {
934-
parallel_tmpdir = tmpdir;
935-
} else {
936-
#ifndef WIN32
937-
if (multiprocessing) {
938-
// char * env_str = std::getenv("SLURM_JOBID");
939-
// if (env_str) {
940-
// parallel_tmpdir = join_path(parallel_tmpdir, "diamond_job_"+string(env_str));
941-
// }
942-
errno = 0;
943-
int s = mkdir(parallel_tmpdir.c_str(), 00770);
944-
if (s != 0) {
945-
if (errno == EEXIST) {
946-
// directory did already exist
947-
} else {
948-
throw(std::runtime_error("could not create parallel temporary directory " + parallel_tmpdir));
949-
}
950-
}
951-
}
952-
#endif
930+
if (multiprocessing && parallel_tmpdir.empty())
931+
throw std::runtime_error("--multiprocessing requires setting --parallel-tmpdir");
932+
933+
if (multiprocessing) {
934+
// char * env_str = std::getenv("SLURM_JOBID");
935+
// if (env_str) {
936+
// parallel_tmpdir = join_path(parallel_tmpdir, "diamond_job_"+string(env_str));
937+
// }
938+
mkdir(parallel_tmpdir);
953939
}
954940

955941
log_stream << "MAX_SHAPE_LEN=" << MAX_SHAPE_LEN;

src/basic/const.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct Const
2525
{
2626

2727
enum {
28-
build_version = 166,
28+
build_version = 167,
2929
max_seed_weight = 32,
3030
max_shapes = 64
3131
};

src/cluster/cascaded/wrapper.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ static vector<SuperBlockId> search_vs_centroids(shared_ptr<FastaFile>& super_blo
160160

161161
void Cascaded::run() {
162162
config.database.require();
163+
init_thresholds();
163164
if (!config.parallel_tmpdir.empty()) {
164165
#ifdef EXTRA
165166
external();
@@ -168,7 +169,6 @@ void Cascaded::run() {
168169
#endif
169170
return;
170171
}
171-
init_thresholds();
172172
config.hamming_ext = config.approx_min_id >= 50.0;
173173

174174
TaskTimer total_time;

src/cluster/external/align.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,29 @@ static void align_rep(ThreadPool& tp, const ChunkSeqs& chunk_seqs, vector<PairEn
3636
}
3737
DP::Params params{ rep, nullptr, Frame(0), rep.length(), nullptr, DP::Flags::FULL_MATRIX, false, max_len, HspValues::COORDS, stats, &tp };
3838
const list<Hsp> hsps = DP::BandedSwipe::swipe(targets, params);
39+
const bool unid = !config.mutual_cover.present();
3940
for (const Hsp& h : hsps) {
4041
const int64_t member_oid = begin[h.swipe_target].member_oid;
4142
const Sequence member = chunk_seqs[member_oid];
4243
if (h.approx_id_percent(rep, member) < config.approx_min_id.get(0))
4344
continue;
44-
if (h.subject_cover_percent(member.length()) >= config.member_cover.get(80))
45-
out.write(MurmurHash()(member_oid) & (RADIX_COUNT - 1), Edge(rep_oid, member_oid, rep.length(), member.length()));
46-
if (h.query_cover_percent(rep.length()) >= config.member_cover.get(80))
47-
out.write(MurmurHash()(rep_oid) & (RADIX_COUNT - 1), Edge(member_oid, rep_oid, member.length(), rep.length()));
45+
if (unid) {
46+
if (h.subject_cover_percent(member.length()) >= config.member_cover.get(80))
47+
out.write(MurmurHash()(member_oid) & (RADIX_COUNT - 1), Edge(rep_oid, member_oid, rep.length(), member.length()));
48+
if (h.query_cover_percent(rep.length()) >= config.member_cover.get(80))
49+
out.write(MurmurHash()(rep_oid) & (RADIX_COUNT - 1), Edge(member_oid, rep_oid, member.length(), rep.length()));
50+
}
51+
else if (h.subject_cover_percent(member.length()) >= config.mutual_cover.get_present() && h.query_cover_percent(rep.length()) >= config.mutual_cover.get_present()) {
52+
int64_t oid1 = rep_oid;
53+
int64_t oid2 = member_oid;
54+
int64_t len1 = rep.length();
55+
int64_t len2 = member.length();
56+
if (oid1 > oid2) {
57+
std::swap(oid1, oid2);
58+
std::swap(len1, len2);
59+
}
60+
out.write(MurmurHash()(oid1) & (RADIX_COUNT - 1), Edge(oid1, oid2, len1, len2));
61+
}
4862
}
4963
}
5064

@@ -95,6 +109,7 @@ vector<string> align(Job& job, int chunk_count, int64_t db_size) {
95109
log_stream << "pairs=" << pairs_processed << endl;
96110
timer.go("Deallocating memory");
97111
pairs_file.close();
112+
remove(pairs_file.file_name.c_str());
98113
chunk_seqs.reset();
99114
++chunks_processed;
100115
timer.finish();
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#pragma once
2+
#include "util/util.h"
3+
#include "util/hash_function.h"
4+
#include "external.h"
5+
6+
namespace Cluster {
7+
8+
struct SeedEntry {
9+
SeedEntry() :
10+
seed(),
11+
oid(),
12+
len()
13+
{}
14+
SeedEntry(uint64_t seed, int64_t oid, int32_t len):
15+
seed(seed),
16+
oid(oid),
17+
len(len)
18+
{}
19+
uint64_t key() const {
20+
return seed;
21+
}
22+
bool operator<(const SeedEntry& e) const {
23+
return seed < e.seed || (seed == e.seed && (len > e.len || (len == e.len && oid < e.oid)));
24+
}
25+
struct Key {
26+
uint64_t operator()(const SeedEntry& e) const {
27+
return e.seed;
28+
}
29+
};
30+
uint64_t seed;
31+
int64_t oid;
32+
int32_t len;
33+
};
34+
35+
void get_pairs_uni_cov(KeyMergeIterator<const SeedEntry*, SeedEntry::Key>& it, BufferArray& buffers) {
36+
const int64_t rep_oid = it.begin()->oid, radix = MurmurHash()(rep_oid) & (RADIX_COUNT - 1);
37+
const int32_t rep_len = it.begin()->len;
38+
for (auto j = it.begin() + 1; j < it.end(); ++j) {
39+
if (rep_oid == j->oid)
40+
continue;
41+
buffers.write(radix, PairEntry(rep_oid, j->oid, rep_len, j->len));
42+
}
43+
}
44+
45+
void get_pairs_mutual_cov(KeyMergeIterator<const SeedEntry*, SeedEntry::Key>& it, BufferArray& buffers) {
46+
const double mlr = config.min_length_ratio;
47+
const int32_t s = (int)it.count();
48+
int32_t j = 0;
49+
const auto begin = it.begin();
50+
for (int32_t i = 0; i < s;) {
51+
const Loc qlen = begin[i].len;
52+
int32_t j1 = j;
53+
for (; j1 < s; ++j1) {
54+
const Loc tlen = begin[j1].len;
55+
if ((double)tlen / qlen < mlr)
56+
break;
57+
}
58+
const int32_t qpos = i + (j1 - j) / 2;
59+
const int64_t rep_oid = begin[qpos].oid;
60+
const int32_t rep_len = begin[qpos].len;
61+
const int64_t radix = MurmurHash()(rep_oid) & (RADIX_COUNT - 1);
62+
for (int k = j; k < j1; ++k)
63+
if (rep_oid != begin[k].oid)
64+
buffers.write(radix, PairEntry(rep_oid, begin[k].oid, rep_len, begin[k].len));
65+
j = j1;
66+
if (j == s)
67+
break;
68+
const Loc tlen = begin[j].len;
69+
for (; i < s; ++i) {
70+
const Loc qlen = begin[i].len;
71+
if ((double)tlen / qlen >= mlr)
72+
break;
73+
}
74+
}
75+
}
76+
77+
}

0 commit comments

Comments
 (0)