我一直在使用Fortran中的ACC和OpenMP进行并行化.我现在正在尝试在matlab中做同样的事情.我觉得非常有趣的是,在matlab中使用GPU来对一个循环进行并行化是非常困难的.显然,唯一的方法是使用arrayfun函数.但我可能错了.
从概念上讲,我想知道为什么matlab中的GPU使用不比fortran更直接.在更实际的层面上,我想知道如何在下面的简单代码中使用GPU.
下面,我将分享三个代码和基准:
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) 我有4个网格:
kgrid 这是[77x1]x 这是[15x1]z 这是[9x1]s 这是[2x1]然后我有一个功能:
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)
这个插值的问题是,给出的输出是所有组合ksim和zsim,这意味着输出为750x750.我确实需要750x1的输出,在所有组合意味着代替插值ksim和zsim我只需要在插值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)
我知道我可以使用这个输出,然后只选择我想要的数字,但这是非常低效的,因为它实际上插入我实际上不需要的所有其他点.任何帮助赞赏.
我有一个双循环,这是非常低效的.
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并且它有效.但我一直在寻找更优雅的解决方案.我一直在努力尝试但没有运气......
我有以下大而非常低效的循环.
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
假设我有一个矩阵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) 我有一个非常低效的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) 我试图对某个加权和进行矢量化,但却无法弄清楚如何去做.我在下面创建了一个简单的最小工作示例.我想这个解决方案涉及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中有以下循环:
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)不是递归的.
我怎么解决这个问题?
在matlab中避免内存不足的任何技巧?我假设它出现的原因是因为matlab在使用horzcat时非常低效,实际上需要临时复制矩阵.
我有一个A大小的矩阵108977555 x 25.我想用三个向量合并本d,m并y与大小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)
合并的任何技巧?
我有一个包含两种类型字符串的单元格数组:'ANN'和'QTR'.
如果单元格数组等于'QTR',我试图用一个向量得到一个向量.
这是我想要做的一个例子:
A = {'ANN';'ANN';'ANN';'ANN'; 'QTR'; 'ANN'; 'QTR'; 'QTR'; 'QTR'; 'QTR'};
logic1 = A == 'QTR'
Run Code Online (Sandbox Code Playgroud)
但是,这种符号似乎不适用于细胞.我寻找解决方法,但没有找到任何解决方法.
任何帮助将非常感激.
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) 我有一个具有几个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)