小编phd*_*ent的帖子

在matlab上的CUDA循环

我一直在使用Fortran中的ACC和OpenMP进行并行化.我现在正在尝试在matlab中做同样的事情.我觉得非常有趣的是,在matlab中使用GPU来对一个循环进行并行化是非常困难的.显然,唯一的方法是使用arrayfun函数.但我可能错了.

从概念上讲,我想知道为什么matlab中的GPU使用不比fortran更直接.在更实际的层面上,我想知道如何在下面的简单代码中使用GPU.

下面,我将分享三个代码和基准:

  1. Fortran OpenMP代码
  2. Fortran ACC代码
  3. Matlab parfor代码
  4. Matlab CUDA(?)这是我不知道怎么做的.

Fortran OpenMP:

program rbc

 use omp_lib     ! For timing
 use tools
 implicit none

 real, parameter :: beta = 0.984, eta = 2, alpha = 0.35, delta = 0.01, &
                     rho = 0.95, sigma = 0.005, zmin=-0.0480384, zmax=0.0480384;
integer, parameter :: nz = 4, nk=4800;
real :: zgrid(nz), kgrid(nk), t_tran_z(nz,nz), tran_z(nz,nz);
real :: kmax, kmin, tol, dif, c(nk), r(nk), w(nk);
real, dimension(nk,nz) :: v=0., v0=0., ev=0., c0=0.;
integer …
Run Code Online (Sandbox Code Playgroud)

matlab openmp openacc

8
推荐指数
1
解决办法
239
查看次数

Interpn - 改变输出

我有4个网格:

  1. kgrid 这是[77x1]
  2. x 这是[15x1]
  3. z 这是[9x1]
  4. s 这是[2x1]

然后我有一个功能:

  1. kprime 这是[77x15x9x2]

我想kprime在某些点插值ksim (750 x 1)并且zsim (750 x 1)(xsim是标量).我在做:

[ks, xs, zs, ss] = ndgrid(kgrid, x, z, [1;2]);
Output = interpn(ks, xs, zs, ss, kprime, ksim, xsim, zsim, 1,'linear');
Run Code Online (Sandbox Code Playgroud)

这个插值的问题是,给出的输出是所有组合ksimzsim,这意味着输出为750x750.我确实需要750x1的输出,在所有组合意味着代替插值ksimzsim我只需要在插值ksim(1,1)zsim(1,1),然后ksim(2,1)zsim(2,1),然后ksim(3,1)zsim(3,1)

换句话说,在Output我做完之后:

Output = diag(squeeze(Output));
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用这个输出,然后只选择我想要的数字,但这是非常低效的,因为它实际上插入我实际上不需要的所有其他点.任何帮助赞赏.

performance matlab interpolation vectorization

7
推荐指数
2
解决办法
230
查看次数

Vectorize Double Loop - MATLAB

我有一个双循环,这是非常低效的.

c is a [400,2000] matrix
r is a [2000,1] matrix
P is a [2000,1] matrix
S is a [1, 400] matrix


for i=1:400
    for k=1:2000
        c(i,k) = r(k,1) * max([0, P(k,1) - S(1,i)]);
    end
end
Run Code Online (Sandbox Code Playgroud)

我试图制作一个parfor并且它有效.但我一直在寻找更优雅的解决方案.我一直在努力尝试但没有运气......

performance matlab vectorization

4
推荐指数
1
解决办法
114
查看次数

Vectorize Triple Loop - MATLAB

我有以下大而非常低效的循环.

P is a [2000 x 200 x 5] matrix
D is a [2000 x 200 x 5] matrix
S is a [200 x 1005] matrix
PS is a [2000 x 1000 x 5] matrix
Run Code Online (Sandbox Code Playgroud)

我想计算以下循环:

for k=1:2000
   for n=1:200
      for t=1:5
          P(k,n,t) = sum(S(n,t+1:t+1000) .* PS(k,1:1000,t));
      end
   end
end
Run Code Online (Sandbox Code Playgroud)

显然这是非常低效的.我尝试过parfor,但我宁愿使用矢量化解决方案.我尝试了几件事bsxfun,但也从未设法让它发挥作用.

谢谢.

performance matlab vectorization processing-efficiency bsxfun

3
推荐指数
1
解决办法
118
查看次数

Fortran - 逻辑索引

假设我有一个矩阵A,其是(m x n)和向量B(m x 1)。这个向量B是一个由零和一组成的向量。

也让标量s是 中元素的总和B

我想创建一个矩阵C,它s x n对应于B等于 1的行,以及一个Dsx 1的向量,这些元素的位置在A.

Take as an example: 

      A = [1, 2, 3; 
           4, 5, 6; 
           7, 8, 9; 
           10, 11, 12; 
           13, 14, 15 ]

        B = [0; 1; 0; 1; 1]

    Then:
C = [ 4, 5, 6; 
     10, 11, 12; 
     13, 14, 15 ]
and …
Run Code Online (Sandbox Code Playgroud)

indexing fortran logical-operators

3
推荐指数
1
解决办法
3156
查看次数

提高matlab的效率

我有一个非常低效的matlab代码,我需要多次运行它.代码基本上是一个大的parfor loop,我想几乎不可能绕过.

代码首先加载几个参数和4-D矩阵,然后需要进行一些插值.所有这些都需要完成5000次(因此parfor循环).

这是代码的样子.我没有取出关键成分,我尽可能地简化了代码.

load file

nsim = 5000
T = 12; 
N = 1000;

cumQx = cumsum(Qx);
cumQz = cumsum(Qz);
cumQs = cumsum(Qs);

for k=1:nsim
st(k).ksim    = kstar*ones(N, T);
st(k).Vsim  = zeros(N,T);  
st(k).Psim = zeros(N,T);   
end


parfor k = 1:nsim    

    sysrand  = rand(T, 1);
    idiorand = rand(N, T);
    sigmarand = rand(T,1);

    xid = zeros(T, 1);
    zid = zeros(N, T);
    sid = zeros(T,1);
    xid(1) = 8;
    zid(:, 1) = 5;
    sid(1) = 1;
    % Initializing the simulation

    simx …
Run Code Online (Sandbox Code Playgroud)

performance matlab parfor

3
推荐指数
1
解决办法
347
查看次数

三重加权和

我试图对某个加权和进行矢量化,但却无法弄清楚如何去做.我在下面创建了一个简单的最小工作示例.我想这个解决方案涉及bsxfun或reshape和kronecker产品,但我仍然没有设法让它工作.

rng(1);
N = 200;
T1 = 5;
T2 = 7;
T3 = 10;


A = rand(N,T1,T2,T3);
w1 = rand(T1,1);
w2 = rand(T2,1);
w3 = rand(T3,1);

B = zeros(N,1);

for i = 1:N
 for j1=1:T1
  for j2=1:T2
   for j3=1:T3
    B(i) = B(i) + w1(j1) * w2(j2) * w3(j3) * A(i,j1,j2,j3);
   end
  end
 end
end

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

对于二维情况下,有一个聪明的答案在这里.

matlab vectorization weighted-average

3
推荐指数
1
解决办法
92
查看次数

矢量化这个循环

我在MATLAB中有以下循环:

n = 20000
rho=0.9;
sigma=[0.1 0.2 0.3];
epsilon = normrnd(0,1, 3, n);
z =  NaN(1,n);
z(1,1) = 0;
for i=2:n
   z(1,i) = rho * z(1,i-1) + sigma* epsilon(:,i);
end
Run Code Online (Sandbox Code Playgroud)

我尝试通过以下方式进行矢量化:

z(1,2:end) = rho * z(1,1:end-1) + sigma * epsilon
Run Code Online (Sandbox Code Playgroud)

它没用.我明白问题是这一点:z(1,2:end) = rho * z(1,1:end-1)不是递归的.

我怎么解决这个问题?

recursion matlab vectorization

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

Matlab Horzcat - 内存不足

在matlab中避免内存不足的任何技巧?我假设它出现的原因是因为matlab在使用horzcat时非常低效,实际上需要临时复制矩阵.

我有一个A大小的矩阵108977555 x 25.我想用三个向量合并本d,my与大小108977555 x 1各.

我的机器有32GB内存,上面的matrice +矢量占用18GB.

现在我想运行以下命令:

A = [A(:,1:3), d, m, y, A(:,5:end)];
Run Code Online (Sandbox Code Playgroud)

但这会产生错误:

Error using horzcat
Out of memory. Type HELP MEMORY for your options.
Run Code Online (Sandbox Code Playgroud)

合并的任何技巧?

memory matlab

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

逻辑索引单元阵列

我有一个包含两种类型字符串的单元格数组:'ANN'和'QTR'.

如果单元格数组等于'QTR',我试图用一个向量得到一个向量.

这是我想要做的一个例子:

A = {'ANN';'ANN';'ANN';'ANN'; 'QTR'; 'ANN'; 'QTR'; 'QTR'; 'QTR'; 'QTR'};
logic1 = A == 'QTR'
Run Code Online (Sandbox Code Playgroud)

但是,这种符号似乎不适用于细胞.我寻找解决方法,但没有找到任何解决方法.

任何帮助将非常感激.

matlab logic cell-array

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

OpenAcc Intel Fortran Compiler

I am trying to compile a code in Fortran using OpenAcc. So far I have been using Intel fortran which supports OpenMP, but apparently does not support OpenAcc. Can anyone suggest a free compiler that supports OpenAcc?

The exact code I am trying to run can be found on this link, but I am pasting it below as well for convenience:

program rbc
use omp_lib     ! For timing
implicit none
real, parameter :: beta = 0.984, eta = 2, alpha …
Run Code Online (Sandbox Code Playgroud)

fortran openacc

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

将NaN替换为最后一个非NaN值

我有一个具有几个NaN值的矩阵,我想用最后一个非NaN值替换那些.矩阵非常大,所以理想情况下我会以矢量化方式进行.

这是一个最小的工作示例:

M = [
NaN NaN NaN 3
7   NaN NaN 1
NaN NaN NaN 9
NaN 6   NaN NaN
NaN NaN NaN NaN
8   NaN NaN 8
NaN 5   NaN NaN
NaN NaN NaN NaN
9   NaN NaN NaN]
Run Code Online (Sandbox Code Playgroud)

输出应该是:

Out = [
NaN NaN NaN 3
7   NaN NaN 1
7   NaN NaN 9
7   6   NaN 9
7   6   NaN 9
8   6   NaN 8
8   5   NaN 8
8   5   NaN 8
9   5   NaN …
Run Code Online (Sandbox Code Playgroud)

matlab replace nan

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