IsoSpecPy 2.5.0__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- IsoSpecPy/Advanced.py +32 -0
- IsoSpecPy/Distributions.py +93 -0
- IsoSpecPy/Formulas.py +71 -0
- IsoSpecPy/IsoSpec++/aligned_ptr.h +638 -0
- IsoSpecPy/IsoSpec++/allocator.h +69 -0
- IsoSpecPy/IsoSpec++/btrd.h +206 -0
- IsoSpecPy/IsoSpec++/composition.h +126 -0
- IsoSpecPy/IsoSpec++/conf.h +38 -0
- IsoSpecPy/IsoSpec++/cwrapper.h +271 -0
- IsoSpecPy/IsoSpec++/dirtyAllocator.h +58 -0
- IsoSpecPy/IsoSpec++/element_lookup.h +36 -0
- IsoSpecPy/IsoSpec++/element_tables.h +50 -0
- IsoSpecPy/IsoSpec++/fasta.h +70 -0
- IsoSpecPy/IsoSpec++/fasta_mods.h +70 -0
- IsoSpecPy/IsoSpec++/fixedEnvelopes.h +418 -0
- IsoSpecPy/IsoSpec++/isa_kernel_impl.h +192 -0
- IsoSpecPy/IsoSpec++/isa_kernels.h +172 -0
- IsoSpecPy/IsoSpec++/isoMath.h +121 -0
- IsoSpecPy/IsoSpec++/isoSpec++.h +801 -0
- IsoSpecPy/IsoSpec++/iso_simd.h +48 -0
- IsoSpecPy/IsoSpec++/marginalTrek++.h +614 -0
- IsoSpecPy/IsoSpec++/misc.h +229 -0
- IsoSpecPy/IsoSpec++/mman.h +67 -0
- IsoSpecPy/IsoSpec++/operators.h +150 -0
- IsoSpecPy/IsoSpec++/platform.h +180 -0
- IsoSpecPy/IsoSpec++/platform_incl.h +33 -0
- IsoSpecPy/IsoSpec++/pod_vector.h +400 -0
- IsoSpecPy/IsoSpec++/summator.h +118 -0
- IsoSpecPy/IsoSpec++/unimod.h +80 -0
- IsoSpecPy/IsoSpec++/unimod_support.h +2169 -0
- IsoSpecPy/IsoSpec++/unimod_table_data.h +1027 -0
- IsoSpecPy/IsoSpecPy.py +1088 -0
- IsoSpecPy/IsoSpecPyOld.py +290 -0
- IsoSpecPy/PeriodicTbl.py +51 -0
- IsoSpecPy/__init__.py +19 -0
- IsoSpecPy/__main__.py +25 -0
- IsoSpecPy/approximations.py +122 -0
- IsoSpecPy/confs_passthrough.py +16 -0
- IsoSpecPy/isoFFI.py +290 -0
- bin/IsoSpecCppPy.dll +0 -0
- isospecpy-2.5.0.dist-info/METADATA +220 -0
- isospecpy-2.5.0.dist-info/RECORD +45 -0
- isospecpy-2.5.0.dist-info/WHEEL +5 -0
- isospecpy-2.5.0.dist-info/licenses/LICENCE +35 -0
- lib/IsoSpecCppPy.lib +0 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2015-2020 Mateusz Łącki and Michał Startek.
|
|
3
|
+
*
|
|
4
|
+
* This file is part of IsoSpec.
|
|
5
|
+
*
|
|
6
|
+
* IsoSpec is free software: you can redistribute it and/or modify
|
|
7
|
+
* it under the terms of the Simplified ("2-clause") BSD licence.
|
|
8
|
+
*
|
|
9
|
+
* IsoSpec is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
12
|
+
*
|
|
13
|
+
* You should have received a copy of the Simplified BSD Licence
|
|
14
|
+
* along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#pragma once
|
|
18
|
+
|
|
19
|
+
#include <cstddef>
|
|
20
|
+
#include "platform.h"
|
|
21
|
+
#include "iso_simd.h"
|
|
22
|
+
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Runtime ISA dispatch.
|
|
25
|
+
//
|
|
26
|
+
// A single binary can carry several builds of the two batched fill kernels --
|
|
27
|
+
// one per instruction-set level -- and pick the best one the CPU actually
|
|
28
|
+
// supports, at run time. This matters because the distributed builds have no
|
|
29
|
+
// -march at all (the PyPI wheel is compiled at the x86-64 baseline, so its
|
|
30
|
+
// vectors are 2 doubles wide), while the machines running them are mostly
|
|
31
|
+
// AVX2-or-better.
|
|
32
|
+
//
|
|
33
|
+
// Why it is built this way, and not the two obvious easier ways:
|
|
34
|
+
//
|
|
35
|
+
// * __attribute__((target(...))) / target_clones() cannot do it.
|
|
36
|
+
// std::experimental::simd fixes its ABI when the templates are instantiated,
|
|
37
|
+
// from the -march preprocessor macros; a target attribute applied afterwards
|
|
38
|
+
// changes only the *encoding*. Measured: fixed_size_simd<double,8> inside a
|
|
39
|
+
// target("avx512f") function on a baseline TU emits nothing but xmm, and
|
|
40
|
+
// native_simd<double> under target_clones still reports 2 lanes. So the
|
|
41
|
+
// levels have to be separate translation units, each with its own -march.
|
|
42
|
+
//
|
|
43
|
+
// * Those TUs must not include the library's own headers. A TU compiled at
|
|
44
|
+
// -march=x86-64-v4 emits VEX/EVEX code into the COMDAT copies of every
|
|
45
|
+
// inline and template function it instantiates, and the linker then picks
|
|
46
|
+
// one copy of each for the whole program -- by link order. Measured: the
|
|
47
|
+
// same two objects linked in the opposite order gave a surviving copy of a
|
|
48
|
+
// shared inline function using %zmm, reachable from baseline code paths,
|
|
49
|
+
// i.e. SIGILL on any CPU without AVX-512.
|
|
50
|
+
//
|
|
51
|
+
// Hence the interface below is deliberately POD-only: raw pointers and doubles,
|
|
52
|
+
// no IsoSpec types, nothing with a definition that could be duplicated. The
|
|
53
|
+
// kernel bodies (isa_kernel_impl.h) are static, and only the tables below have
|
|
54
|
+
// external linkage. libstdc++'s simd internals are all always_inline, so they
|
|
55
|
+
// leave no mergeable symbols behind either -- verified with nm on both TUs.
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
|
|
58
|
+
namespace IsoSpec
|
|
59
|
+
{
|
|
60
|
+
|
|
61
|
+
//! Batch-emit configurations of the current marginal-0 run into out_masses/out_probs.
|
|
62
|
+
/*!
|
|
63
|
+
Consumes as much of the run as fills whole vectors, leaving the remaining
|
|
64
|
+
fewer-than-W configurations to the caller's scalar drain. Advances
|
|
65
|
+
*lProbs_ptr past what it consumed and returns how many it emitted.
|
|
66
|
+
|
|
67
|
+
\param lProbs_ptr In/out cursor; on entry it points at the last-emitted
|
|
68
|
+
configuration, per the generators' "advance, then emit"
|
|
69
|
+
convention.
|
|
70
|
+
\param lProbs_start Index 0 of marginal 0's log-probability array.
|
|
71
|
+
\param marginal_masses, marginal_probs Marginal 0's tables, indexed as lProbs is.
|
|
72
|
+
\param lcfmsv The cutoff the run ends at.
|
|
73
|
+
\param partial_mass, partial_prob The higher marginals' contribution, constant
|
|
74
|
+
across the run.
|
|
75
|
+
*/
|
|
76
|
+
typedef std::size_t (*isa_fill_run_fn)(const double** lProbs_ptr,
|
|
77
|
+
const double* lProbs_start,
|
|
78
|
+
const double* marginal_masses,
|
|
79
|
+
const double* marginal_probs,
|
|
80
|
+
double lcfmsv,
|
|
81
|
+
double partial_mass,
|
|
82
|
+
double partial_prob,
|
|
83
|
+
double* out_masses,
|
|
84
|
+
double* out_probs);
|
|
85
|
+
|
|
86
|
+
//! As above, but scattering into a dense bin accumulator instead of storing.
|
|
87
|
+
/*! acc must already be rebased so that a bin index of any sign is in range. */
|
|
88
|
+
typedef std::size_t (*isa_bin_run_fn)(const double** lProbs_ptr,
|
|
89
|
+
const double* lProbs_start,
|
|
90
|
+
const double* marginal_masses,
|
|
91
|
+
const double* marginal_probs,
|
|
92
|
+
double lcfmsv,
|
|
93
|
+
double partial_mass,
|
|
94
|
+
double partial_prob,
|
|
95
|
+
double* acc,
|
|
96
|
+
double hwmm,
|
|
97
|
+
double inv_bin_width);
|
|
98
|
+
|
|
99
|
+
//! One instruction-set level's build of the kernels.
|
|
100
|
+
struct IsaKernels {
|
|
101
|
+
isa_fill_run_fn fill_run;
|
|
102
|
+
isa_bin_run_fn bin_run;
|
|
103
|
+
const char* name; /*!< For diagnostics and the tests. */
|
|
104
|
+
std::size_t lanes; /*!< Doubles per vector; 1 when there is no SIMD at all. */
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
//! ISA levels, ordered by capability. Only ever grows at the top.
|
|
108
|
+
/*! The numeric order IS the capability order -- best_available_level() picks the
|
|
109
|
+
highest usable value -- so a new level in the middle renumbers the ones above
|
|
110
|
+
it. That is an ABI break for anything already compiled against this header,
|
|
111
|
+
and is why ISA_LEVEL_AVX was inserted before 2.4.0 shipped rather than after.
|
|
112
|
+
Any level added from now on goes on the top, or the ordering stops being
|
|
113
|
+
expressible as `<`.
|
|
114
|
+
|
|
115
|
+
Note there is deliberately no x86-64-v2 level: v2 is SSE4.2 and POPCNT, which
|
|
116
|
+
do not widen a vector of doubles at all, so it would be identical to the
|
|
117
|
+
baseline in every way that matters here. */
|
|
118
|
+
enum IsaLevel {
|
|
119
|
+
ISA_LEVEL_BASELINE = 0, /*!< Whatever the unadorned target gives: SSE2 on x86-64, NEON on AArch64. */
|
|
120
|
+
ISA_LEVEL_AVX = 1, /*!< AVX without AVX2: 4 doubles, no FMA. Sandy/Ivy Bridge, Bulldozer-Excavator. */
|
|
121
|
+
ISA_LEVEL_V3 = 2, /*!< x86-64-v3: AVX2 + FMA, 4 doubles. */
|
|
122
|
+
ISA_LEVEL_V4 = 3, /*!< x86-64-v4: AVX-512F/BW/DQ/VL, 8 doubles. */
|
|
123
|
+
ISA_LEVEL_COUNT = 4
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
//! The kernels selected for this machine. Resolved once, on first call.
|
|
127
|
+
const IsaKernels& isa_kernels();
|
|
128
|
+
|
|
129
|
+
//! The level those kernels came from.
|
|
130
|
+
IsaLevel current_isa_level();
|
|
131
|
+
|
|
132
|
+
//! Highest level this build contains *and* this CPU supports.
|
|
133
|
+
IsaLevel max_supported_isa_level();
|
|
134
|
+
|
|
135
|
+
//! Is this level present in the binary and usable on this CPU?
|
|
136
|
+
bool isa_level_available(IsaLevel level);
|
|
137
|
+
|
|
138
|
+
//! Force a level, for testing and for working around a bad CPU.
|
|
139
|
+
/*! Returns false and changes nothing if the level is not available. Also
|
|
140
|
+
settable through the ISOSPEC_ISA_LEVEL environment variable
|
|
141
|
+
("baseline", "v3", "v4"), read when the selection is first resolved. */
|
|
142
|
+
bool set_isa_level(IsaLevel level);
|
|
143
|
+
|
|
144
|
+
const char* isa_level_name(IsaLevel level);
|
|
145
|
+
|
|
146
|
+
//! What the batched kernels actually running on this machine are vectorised to.
|
|
147
|
+
/*!
|
|
148
|
+
A stable lowercase token, never NULL and never to be freed: one of
|
|
149
|
+
|
|
150
|
+
- "scalar" -- no vectorisation at all. Either the standard library has no
|
|
151
|
+
<experimental/simd> (MSVC, and Apple Clang's libc++), or the
|
|
152
|
+
build disabled the SIMD path; every configuration goes
|
|
153
|
+
through the scalar drain and the kernels are do-nothing stubs.
|
|
154
|
+
- "sse2" -- x86-64's guaranteed baseline, 2 doubles per vector.
|
|
155
|
+
- "avx" -- 4 doubles, no FMA (a -march build targeting pre-Haswell x86).
|
|
156
|
+
- "avx2" -- x86-64-v3: AVX2+FMA, 4 doubles.
|
|
157
|
+
- "avx512" -- x86-64-v4: AVX-512F/BW/DQ/VL, 8 doubles.
|
|
158
|
+
- "neon" -- AArch64's guaranteed baseline, 2 doubles.
|
|
159
|
+
- "simd" -- vectorised, on an architecture this function has no name for.
|
|
160
|
+
|
|
161
|
+
This is a finer-grained question than current_isa_level(), and deliberately
|
|
162
|
+
so: that one names the dispatch bucket, which says nothing about whether the
|
|
163
|
+
bucket's kernels vectorise. A build whose standard library lacks the SIMD
|
|
164
|
+
header still reports level "baseline" while running entirely scalar -- the
|
|
165
|
+
case this function exists to make visible.
|
|
166
|
+
|
|
167
|
+
New tokens may be added as levels are; treat an unrecognised one as "some
|
|
168
|
+
vector unit", not as an error.
|
|
169
|
+
*/
|
|
170
|
+
const char* active_simd_level();
|
|
171
|
+
|
|
172
|
+
} // namespace IsoSpec
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2015-2020 Mateusz Łącki and Michał Startek.
|
|
3
|
+
*
|
|
4
|
+
* This file is part of IsoSpec.
|
|
5
|
+
*
|
|
6
|
+
* IsoSpec is free software: you can redistribute it and/or modify
|
|
7
|
+
* it under the terms of the Simplified ("2-clause") BSD licence.
|
|
8
|
+
*
|
|
9
|
+
* IsoSpec is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
12
|
+
*
|
|
13
|
+
* You should have received a copy of the Simplified BSD Licence
|
|
14
|
+
* along with IsoSpec. If not, see <https://opensource.org/licenses/BSD-2-Clause>.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#pragma once
|
|
18
|
+
|
|
19
|
+
#include <atomic>
|
|
20
|
+
#include <cmath>
|
|
21
|
+
#include <cstddef>
|
|
22
|
+
#include <cstdint>
|
|
23
|
+
#include <random>
|
|
24
|
+
|
|
25
|
+
#if !defined(ISOSPEC_G_FACT_TABLE_SIZE)
|
|
26
|
+
// 10M should be enough for anyone, right?
|
|
27
|
+
// Actually, yes. If anyone tries to input a molecule that has more than 10M atoms,
|
|
28
|
+
// he deserves to get an exception thrown in his face. OpenMS guys don't want to alloc
|
|
29
|
+
// a table of 10M to memoize the necessary values though, use something smaller for them.
|
|
30
|
+
#if ISOSPEC_BUILDING_OPENMS
|
|
31
|
+
#define ISOSPEC_G_FACT_TABLE_SIZE 1024
|
|
32
|
+
#else
|
|
33
|
+
#define ISOSPEC_G_FACT_TABLE_SIZE 1024*1024*10
|
|
34
|
+
#endif
|
|
35
|
+
#endif
|
|
36
|
+
|
|
37
|
+
// Prefix of g_lfact_table that is filled eagerly at startup. Accessing those
|
|
38
|
+
// entries needs no synchronisation (immutable post-init); the lazy tail above
|
|
39
|
+
// goes through std::atomic_ref to keep the racing fill thread-safe.
|
|
40
|
+
#if !defined(ISOSPEC_LFACT_EAGER_FILL)
|
|
41
|
+
#if ISOSPEC_BUILDING_OPENMS
|
|
42
|
+
#define ISOSPEC_LFACT_EAGER_FILL ISOSPEC_G_FACT_TABLE_SIZE
|
|
43
|
+
#else
|
|
44
|
+
#define ISOSPEC_LFACT_EAGER_FILL 65536
|
|
45
|
+
#endif
|
|
46
|
+
#endif
|
|
47
|
+
|
|
48
|
+
namespace IsoSpec
|
|
49
|
+
{
|
|
50
|
+
|
|
51
|
+
extern double* g_lfact_table;
|
|
52
|
+
|
|
53
|
+
static inline double minuslogFactorial(int n)
|
|
54
|
+
{
|
|
55
|
+
if (n < 2)
|
|
56
|
+
return 0.0;
|
|
57
|
+
if (static_cast<std::size_t>(n) < static_cast<std::size_t>(ISOSPEC_LFACT_EAGER_FILL))
|
|
58
|
+
return g_lfact_table[n]; // immutable after startup
|
|
59
|
+
|
|
60
|
+
#if ISOSPEC_BUILDING_OPENMS
|
|
61
|
+
if (n >= ISOSPEC_G_FACT_TABLE_SIZE)
|
|
62
|
+
return -lgamma(n+1);
|
|
63
|
+
#endif
|
|
64
|
+
|
|
65
|
+
std::atomic_ref<double> slot(g_lfact_table[n]);
|
|
66
|
+
double v = slot.load(std::memory_order_relaxed);
|
|
67
|
+
if (v == 0.0) {
|
|
68
|
+
v = -lgamma(n+1);
|
|
69
|
+
slot.store(v, std::memory_order_relaxed);
|
|
70
|
+
}
|
|
71
|
+
return v;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const double pi = 3.14159265358979323846264338328;
|
|
75
|
+
const double logpi = 1.144729885849400174143427351353058711647294812915311571513623071472137769884826079783623270275489708;
|
|
76
|
+
|
|
77
|
+
double NormalCDFInverse(double p);
|
|
78
|
+
double NormalCDFInverse(double p, double mean, double stdev);
|
|
79
|
+
double NormalCDF(double x, double mean, double stdev);
|
|
80
|
+
double NormalPDF(double x, double mean = 0.0, double stdev = 1.0);
|
|
81
|
+
|
|
82
|
+
// Returns lower incomplete gamma function of a/2, x, where a is int and > 0.
|
|
83
|
+
double LowerIncompleteGamma2(int a, double x);
|
|
84
|
+
|
|
85
|
+
// Returns y such that LowerIncompleteGamma2(a, y) == x. Approximately.
|
|
86
|
+
double InverseLowerIncompleteGamma2(int a, double x);
|
|
87
|
+
|
|
88
|
+
// Computes the inverse Cumulative Distribution Funcion of the Chi-Square distribution with k degrees of freedom
|
|
89
|
+
inline double InverseChiSquareCDF2(int k, double x)
|
|
90
|
+
{
|
|
91
|
+
return InverseLowerIncompleteGamma2(k, x*tgamma(static_cast<double>(k)/2.0)) * 2.0;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
extern thread_local std::mt19937 random_gen;
|
|
95
|
+
|
|
96
|
+
//! Uniform draw from [0,1), 53-bit resolution.
|
|
97
|
+
/*! Not std::uniform_real_distribution: libstdc++ routes that through
|
|
98
|
+
std::generate_canonical, which takes std::log2 of a long double at every
|
|
99
|
+
call -- __ieee754_logl alone was 21% of FromStochastic's runtime profile.
|
|
100
|
+
Two raw 32-bit draws glued into a 53-bit mantissa produce the same
|
|
101
|
+
distribution directly. Measured: 1.51x end-to-end on FromStochastic
|
|
102
|
+
(C23832H37816N6528O7031S170, 3e7 molecules, Piledriver). */
|
|
103
|
+
inline double rdvariate_unif01(std::mt19937& rgen = random_gen)
|
|
104
|
+
{
|
|
105
|
+
uint64_t hi = rgen();
|
|
106
|
+
uint64_t lo = rgen();
|
|
107
|
+
return static_cast<double>(((hi << 32) | lo) >> 11) * 0x1.0p-53;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
inline double rdvariate_beta_1_b(double b, std::mt19937& rgen = random_gen)
|
|
111
|
+
{
|
|
112
|
+
return 1.0 - pow(rdvariate_unif01(rgen), 1.0/b);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
size_t rdvariate_binom(size_t tries, double succ_prob, std::mt19937& rgen = random_gen);
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
} // namespace IsoSpec
|