标签: vectorization

在列表中获取匹配索引的快捷方法

给定一个a包含不等长度向量的列表和一个b包含来自向量的元素的向量的列表a,我想得到一个等长的向量来b包含匹配a元素的索引b(这是我所知道的一个不好的解释)...

以下代码完成了这项工作:

a <- list(1:3, 4:5, 6:9)
b <- c(2, 3, 5, 8)

sapply(b, function(x, list) which(unlist(lapply(list, function(y, z) z %in% y, z=x))), list=a)
[1] 1 1 2 3
Run Code Online (Sandbox Code Playgroud)

sapply当然,用for循环替换也可以实现相同的目的

问题是这个代码将用于长度大于1000的列表和向量.在现实生活中,该函数大约需要15秒(for循环和for sapply).

有没有人知道如何加快速度,对并行方法安全?我没有看到矢量化方法(我不能用C编程,尽管这可能是最快的).

编辑:

只会强调Aaron使用match()的优雅解决方案,其速度提升1667次(从15到0.009)

我在它上面扩展了一下以允许多个匹配(返回是一个列表)

a <- list(1:3, 3:5, 3:7)
b <- c(3, 5)
g <- rep(seq_along(a), sapply(a, length))
sapply(b, function(x) g[which(unlist(a) %in% x)])
[[1]]
[1] 1 2 3

[[2]]
[1] 2 3
Run Code Online (Sandbox Code Playgroud)

这个的运行时间是0.169,这可能相当慢,但另一方面更灵活

indexing optimization r list vectorization

15
推荐指数
1
解决办法
2万
查看次数

矢量化冒号(:)的概念 - 在MATLAB中两个向量之间的值

我有两个向量,idx1并且idx2,我想获得它们之间的值.如果idx1idx2是数字,而不是载体,我能做到这一点的方式如下:

idx1=1;
idx2=5;
values=idx1:idx2 

% Result
 % values =
 % 
 %    1     2     3     4     5
Run Code Online (Sandbox Code Playgroud)

但在我的情况下,idx1并且idx2是可变长度的向量.例如,对于length = 2:

idx1=[5,9];
idx2=[9 11];
Run Code Online (Sandbox Code Playgroud)

我可以使用冒号运算符直接获取其间的值吗?这是类似于以下内容:

values = [5     6     7     8     9     9    10    11]
Run Code Online (Sandbox Code Playgroud)

我知道我可以做idx1(1):idx2(1)idx1(2):idx2(2),这是单独提取各列的值,因此,如果没有其他的解决方案,我可以用一个for循环做到这一点,但也许Matlab的可以更容易地做到这一点.

matlab vector vectorization colon

15
推荐指数
1
解决办法
3439
查看次数

HPC编程语言依赖于隐式向量化

是否存在依赖于隐式向量化的编程语言或语言扩展?

对于标量C代码的单/双精度的SSE4.1,AVX,AVX2(有或没有FMA3/4),我需要做出积极的假设来生成良好的DLP /向量化代码.

在过去的10年里,我依靠英特尔的内在函数来编写我的HPC内核,并明确地进行了矢量化.与此同时,我经常对C/C++编译器(GCC,clang,LLVM等)生成的DLP代码的质量感到失望,如果你问,我可以发布具体的例子.

内在指南来看,很明显,为现代平台编写带有内在函数的"手动"HPC内核不再是一个可持续的选择,除非我有一大批程序员.太多版本和组合:SSE4.1,AVX,AVX2,AVX512 +口味,FMA,SP,DP,半精度?如果我的目标平台是2012年以来最普遍的平台,那就不可持续了.

我最近尝试过针对OpenCL(CPU)的英特尔离线编译器.我编写了内核"a la CUDA"(即标量代码,隐式向量化),令我惊讶的是生成的程序集非常好地矢量化了!(Skylake,SP中的AVX2 + FMA)我遇到的唯一限制是缺少内置的数据缩减/互通通信功能,而不依赖于共享内存(可转换为CPU水平添加或shuffle + min/max操作) .

正如clemens和sschuberth所指出的那样,离线编译器并不是真正的解决方案,除非我不完全接受OpenCL.或者我破解我的调用者代码以遵守生成的程序集的调用约定,其中包括我不需要的参数,例如ndrange.完全接受OpenCL对我来说也不是一个选择,因为对于TLP我依赖于OpenMP和Pthreads(对于ILP,我依赖于硬件).

更新

首先,值得回顾一下隐式矢量化和自动矢量化并不是一回事.事实上,我对自动向量化失去了希望(如上所述).不在隐式矢量化中.

下面的答案之一是要求一些代码示例. 这里我提供了一个内核的代码示例,该内核在三维结构块上实现NSE对流项的三阶逆风方案.值得一提的是,这代表了一个 简单的例子,因为不需要SIMD通道间合作/通信.

c hpc vectorization opencl

15
推荐指数
2
解决办法
956
查看次数

如何在data.table中编写累积计算

连续的累积计算

我需要进行时间序列计算,其中每行计算的值取决于前一行中计算的结果.我希望使用方便data.table.实际问题是水文模型 - 累积水量平衡计算,在每个时间步骤增加降雨量,减去径流和蒸发量作为当前水量的函数.数据集包括不同的盆地和场景(组).在这里,我将使用更简单的问题说明.

对于每个时间步(行),计算的简化示例如下所示i:

 v[i] <- a[i] + b[i] * v[i-1]
Run Code Online (Sandbox Code Playgroud)

a并且b是参数值的向量,并且v是结果向量.对于第一行(i == 1)的初始值v取为v0 = 0.

第一次尝试

我首先想到的是使用shift()data.table.最小的例子,包括期望的结果v.ans,是

library(data.table)        # version 1.9.7
DT <- data.table(a = 1:4, 
                 b = 0.1,
                 v.ans = c(1, 2.1, 3.21, 4.321) )
DT
#    a   b v.ans
# 1: 1 0.1 1.000
# 2: 2 0.1 2.100
# 3: 3 0.1 3.210
# …
Run Code Online (Sandbox Code Playgroud)

r time-series vectorization difference-equations data.table

15
推荐指数
1
解决办法
749
查看次数

使用Eigen的子矩阵和指数

我正在研究一个MATLAB项目,我想用C++和Eigen重新实现计算量最大的部分.我想知道是否有办法执行以下操作(MATLAB语法):

B = A(A < 3);
Run Code Online (Sandbox Code Playgroud)

对于那些不熟悉MATLAB的人,上述命令初始化由A中单元格构成的矩阵B,其值小于3.

我从Eigen论坛的帖子中看到,可以通过以下方式获得感兴趣的指数:

MatrixXi indices = (A.array() < 3).cast<int>();
Run Code Online (Sandbox Code Playgroud)

我想拥有的是:

MatrixXd B = A(A.array() < 3);
Run Code Online (Sandbox Code Playgroud)

谢谢.

c++ vectorization submatrix eigen

14
推荐指数
3
解决办法
9701
查看次数

如何向量化这个python代码?

我正在尝试使用NumPy和矢量化操作来使代码段运行得更快.然而,我似乎误解了如何对这段代码进行矢量化(可能是由于对矢量化的理解不完全).

这是带循环的工作代码(A和B是已设置大小的2D数组,已经初始化):

for k in range(num_v):
    B[:] = A[:]
    for i in range(num_v):
        for j in range(num_v):
            A[i][j] = min(B[i][j], B[i][k] + B[k][j])
return A
Run Code Online (Sandbox Code Playgroud)

这是我尝试矢量化上面的代码:

for k in range(num_v):
    B = numpy.copy(A)
    A = numpy.minimum(B, B[:,k] + B[k,:])
return A
Run Code Online (Sandbox Code Playgroud)

为了测试这些,我使用了以下代码,上面的代码包含在一个名为'algorithm'的函数中:

def setup_array(edges, num_v):
    r = range(1, num_v + 1)
    A = [[None for x in r] for y in r]  # or (numpy.ones((num_v, num_v)) * 1e10) for numpy
    for i in r:
        for j in r:
            val = …
Run Code Online (Sandbox Code Playgroud)

python numpy vectorization

14
推荐指数
2
解决办法
1万
查看次数

在R中真的快速字ngram矢量化

编辑:新包text2vec非常好,并且很好地解决了这个问题(和许多其他问题).

关于github 插图的CRAN text2vec上的text2vec,用于说明ngram标记化

我在R中有一个非常大的文本数据集,我已将其作为字符向量导入:

#Takes about 15 seconds
system.time({
  set.seed(1)
  samplefun <- function(n, x, collapse){
    paste(sample(x, n, replace=TRUE), collapse=collapse)
  }
  words <- sapply(rpois(10000, 3) + 1, samplefun, letters, '')
  sents1 <- sapply(rpois(1000000, 5) + 1, samplefun, words, ' ')
})
Run Code Online (Sandbox Code Playgroud)

我可以将此字符数据转换为词袋表示,如下所示:

library(stringi)
library(Matrix)
tokens <- stri_split_fixed(sents1, ' ')
token_vector <- unlist(tokens)
bagofwords <- unique(token_vector)
n.ids <- sapply(tokens, length)
i <- rep(seq_along(n.ids), n.ids)
j <- match(token_vector, bagofwords)
M <- sparseMatrix(i=i, j=j, x=1L)
colnames(M) <- bagofwords
Run Code Online (Sandbox Code Playgroud)

所以R可以在大约3秒钟内将1,000,000,000个短句矢量化为一个单词表示形式(不错!):

> M[1:3, …
Run Code Online (Sandbox Code Playgroud)

r vectorization text-mining n-gram text2vec

14
推荐指数
1
解决办法
3740
查看次数

GCC C向量扩展:如何检查任何元素比较的结果是否为真,哪个?

我是GCC的C矢量扩展的新手.根据手册,将一个向量与另一个向量进行比较的结果(test = vec1> vec2;)是"test"在每个元素中包含0,为false,每个元素中为-1为真.

但是如何快速检查是否有任何元素比较是真的?而且,进一步说,如何判断哪个是比较真实的第一个元素?

例如,用:

vec1 = {1,1,3,1};
vec2 = {1,2,2,2};
test = vec1 > vec2;
Run Code Online (Sandbox Code Playgroud)

我想确定"test"是否包含任何真值(非零元素).在这种情况下,我希望"test"减少为true,因为存在一个vec1大于vec2的元素,因此test中的元素包含-1.

另外,或者,我想快速发现WHICH元素未通过测试.在这种情况下,这只是数字2.换句话说,我想测试哪个是第一个非零元素.

int hasAnyTruth = ...; // should be non-zero. "bool" works too since C99
int whichTrue = ...; // should contain 2, because test[2] == -1
Run Code Online (Sandbox Code Playgroud)

我想我们可以使用simd reduction-addition命令(?)将向量中的所有内容加到一个数字中并将该总和与0进行比较,但我不知道如何(或者是否有更快的方法).我猜第二个问题需要某种形式的argmax,但同样,我不知道如何指示GCC在矢量上使用它.

c comparison performance gcc vectorization

14
推荐指数
1
解决办法
768
查看次数

使用SSE计算绝对值的最快方法

我知道3种方法,但据我所知,通常只使用前2种方法:

  1. 使用andps或屏蔽符号位andnotps.

    • 优点:一个快速指令,如果掩码已经在寄存器中,这使得它非常适合在循环中多次执行此操作.
    • 缺点:掩码可能不在寄存器中或更糟糕,甚至不在缓存中,导致非常长的内存提取.
  2. 将值从零减去否定,然后得到原始的最大值并否定.

    • 优点:固定成本,因为无需取物,就像面具一样.
    • 缺点:如果条件理想,将始终比掩码方法慢,并且我们必须等待subps完成才能使用该maxps指令.
  3. 与选项2类似,将原始值从零减去否定,但随后使用原始值"按位"和"按位" andps.我运行了一个测试,将其与方法2进行比较,除了处理NaNs 之外,它似乎与方法2的行为相同,在这种情况下,结果将NaN与方法2的结果不同.

    • 优点:应该比方法2略快,因为andps通常比速度快maxps.
    • 缺点:当NaN涉及到s 时,这是否会导致任何意外行为?也许不是,因为a NaN仍然是a NaN,即使它是一个不同的值NaN,对吧?

欢迎提出想法和意见.

x86 sse simd vectorization absolute-value

14
推荐指数
1
解决办法
5397
查看次数

gensim如何计算doc2vec段落向量

我要去看这篇论文http://cs.stanford.edu/~quocle/paragraph_vector.pdf

它说明了这一点

"对图矢量和单词矢量进行平均或连接以预测上下文中的下一个单词.在实验中,我们使用连接作为组合矢量的方法."

连接或平均如何工作?

示例(如果第1段包含word1和word2):

word1 vector =[0.1,0.2,0.3]
word2 vector =[0.4,0.5,0.6]

concat method 
does paragraph vector = [0.1+0.4,0.2+0.5,0.3+0.6] ?

Average method 
does paragraph vector = [(0.1+0.4)/2,(0.2+0.5)/2,(0.3+0.6)/2] ?
Run Code Online (Sandbox Code Playgroud)

也是从这张图片:

据说:

段落标记可以被认为是另一个单词.它充当记忆,记住当前上下文中缺少的内容 - 或段落的主题.出于这个原因,我们经常将此模型称为段落向量的分布式存储模型(PV-DM).

段落标记是否等于段落向量等于on

在此输入图像描述

nlp vectorization gensim word2vec doc2vec

14
推荐指数
1
解决办法
1923
查看次数