在 Chapel 中,有没有一种方便的方法可以用随机值填充稀疏数组?
Is there a convenient way to fill a sparse array with random values in Chapel?
我正在比较使用和不使用语言环境的矩阵乘法,我正在尝试使用稀疏矩阵来处理线性代数模块。我计划使用 blockdist 并通过循环手动将其分解,但我希望能够看看我现在是否可以仅使用更简单的方法来获得加速。如果有一种我忽略的使用 blockdist 的简单方法,我将不胜感激。无论如何,当我只用一个值填充稀疏数组时,我能够让代码工作并看到加速,但是用随机值填充它似乎不起作用:
use LayoutCS;
use Time;
use LinearAlgebra, Norm;
use LinearAlgebra.Sparse;
use Random;
use IO;
writeln("Please type the filename with your matrix dimensions. One matrix on each line. The rows in the second need to match the columns in the first");
var filename: string;
filename = stdin.read(string);
// Open an input file with the specified filename in read mode.
var infile = open(filename, iomode.r);
var reader = infile.reader();
// Read the number of rows and columns in the array in from the file.
var r = reader.read(int), c = reader.read(int);
const parentDom = {1..r, 1..c};
var csrDom: sparse subdomain(parentDom) dmapped CS();
var A: [csrDom] real;
A = 2; //instead of this I would like to do something like fillRandom(A) but it seems to not work
var X: [1..r, 1..c] real;
fillRandom(X);
//read in the other matrix
var r1 = reader.read(int), c1 = reader.read(int);
const parentDom1 = {1..r1, 1..c1};
var csrDom1: sparse subdomain(parentDom1) dmapped CS();
var B: [csrDom1] real;
B = 3; //same thing as with matrix A
var Y: [1..r1, 1..c1] real;
fillRandom(Y);
// Close the file.
reader.close();
infile.close();
var t: Timer; //sets up timer
t.start();
var result: [1..r, 1..c1] real; //sets up matrix for results
forall i in 1..r do //goes through rows in 1st
for j in 1..c1 do //goes through 2nd matrix columns
for k in 1..c do { //goes through columns in 1st
result[i, j] += X[i, k] * Y[k, j]; //adds the multiplications to the new slot in results
}
t.stop();
writeln("multiplication took ", t.elapsed()," seconds");
t.clear();
t.start();
var res = A * B;
t.stop();
writeln("loc multiplication took ", t.elapsed()," seconds");
t.clear();
fillRandom 不适用于稀疏数组还是我做错了?我是否需要通过循环手动分配数组中的每个值?当然,我也有可能走上了完全错误的道路,应该更多地关注 blockdist,我非常感谢有关这方面的任何建议或提示,因为我不太确定我将如何工作以确保每个并行任务实际上是 运行 在 blockdist 创建的正确语言环境部分上。
提前致谢!
Does fillRandom not work with sparse arrays or am I doing it incorrectly?
Random.fillRandom()
在今天的 Chapel (1.22.0) 中不支持稀疏数组。但是,我认为这将是一个合理的功能请求,如果您有兴趣就此提出 GitHub 问题。
即使 fillRandom
支持稀疏数组,用户仍然需要在用随机值填充那些 non-zero 元素之前指定哪些元素是 non-zero。这是通过将索引作为 (int, int)
元组(或 (int, int)
元组的数组)添加到稀疏域来完成的。
下面是一个生成 100x100 压缩稀疏行 (CSR) 数组的小示例,其中包含 10 个 non-zero 个随机元素:
/* Example tested with Chapel 1.22 */
import LayoutCS.{CS, isCSType};
import Random;
/* Parent domain dimensions: NxN */
config const N = 100;
/* Number of non-zero elements */
config const nnz = 10;
const parentDom = {1..N, 1..N};
var csrDom: sparse subdomain(parentDom) dmapped CS();
var A: [csrDom] real;
populate(A, csrDom, nnz);
// Print non-zero elements
for (i,j) in csrDom do
writeln((i,j), ':', A[i, j]);
/* Populate sparse matrix with `nnz` random values */
proc populate(ref A, ref ADom, nnz: int) where isCSType(ADom.dist.type) && isCSType(A.domain.dist.type) {
// Generate array of random non-zero indices
var indices: [1..nnz] 2*int;
var randomIndices = Random.createRandomStream(eltType=int);
// Replace any duplicate indices with a new random index
for idx in indices {
var newIdx = idx;
while indices.find(newIdx)(1) {
newIdx = (randomIndices.getNext(ADom.dim(0).low, ADom.dim(0).high),
randomIndices.getNext(ADom.dim(1).low, ADom.dim(1).high));
}
idx = newIdx;
}
// Add the non-zero indices to the CSR domain
ADom += indices;
// Generate random elements - maybe fillRandom(A) could do this for us some day
var randomElements = Random.createRandomStream(eltType=A.eltType);
for idx in ADom {
A[idx] = randomElements.getNext();
}
}
我正在比较使用和不使用语言环境的矩阵乘法,我正在尝试使用稀疏矩阵来处理线性代数模块。我计划使用 blockdist 并通过循环手动将其分解,但我希望能够看看我现在是否可以仅使用更简单的方法来获得加速。如果有一种我忽略的使用 blockdist 的简单方法,我将不胜感激。无论如何,当我只用一个值填充稀疏数组时,我能够让代码工作并看到加速,但是用随机值填充它似乎不起作用:
use LayoutCS;
use Time;
use LinearAlgebra, Norm;
use LinearAlgebra.Sparse;
use Random;
use IO;
writeln("Please type the filename with your matrix dimensions. One matrix on each line. The rows in the second need to match the columns in the first");
var filename: string;
filename = stdin.read(string);
// Open an input file with the specified filename in read mode.
var infile = open(filename, iomode.r);
var reader = infile.reader();
// Read the number of rows and columns in the array in from the file.
var r = reader.read(int), c = reader.read(int);
const parentDom = {1..r, 1..c};
var csrDom: sparse subdomain(parentDom) dmapped CS();
var A: [csrDom] real;
A = 2; //instead of this I would like to do something like fillRandom(A) but it seems to not work
var X: [1..r, 1..c] real;
fillRandom(X);
//read in the other matrix
var r1 = reader.read(int), c1 = reader.read(int);
const parentDom1 = {1..r1, 1..c1};
var csrDom1: sparse subdomain(parentDom1) dmapped CS();
var B: [csrDom1] real;
B = 3; //same thing as with matrix A
var Y: [1..r1, 1..c1] real;
fillRandom(Y);
// Close the file.
reader.close();
infile.close();
var t: Timer; //sets up timer
t.start();
var result: [1..r, 1..c1] real; //sets up matrix for results
forall i in 1..r do //goes through rows in 1st
for j in 1..c1 do //goes through 2nd matrix columns
for k in 1..c do { //goes through columns in 1st
result[i, j] += X[i, k] * Y[k, j]; //adds the multiplications to the new slot in results
}
t.stop();
writeln("multiplication took ", t.elapsed()," seconds");
t.clear();
t.start();
var res = A * B;
t.stop();
writeln("loc multiplication took ", t.elapsed()," seconds");
t.clear();
fillRandom 不适用于稀疏数组还是我做错了?我是否需要通过循环手动分配数组中的每个值?当然,我也有可能走上了完全错误的道路,应该更多地关注 blockdist,我非常感谢有关这方面的任何建议或提示,因为我不太确定我将如何工作以确保每个并行任务实际上是 运行 在 blockdist 创建的正确语言环境部分上。
提前致谢!
Does fillRandom not work with sparse arrays or am I doing it incorrectly?
Random.fillRandom()
在今天的 Chapel (1.22.0) 中不支持稀疏数组。但是,我认为这将是一个合理的功能请求,如果您有兴趣就此提出 GitHub 问题。
即使 fillRandom
支持稀疏数组,用户仍然需要在用随机值填充那些 non-zero 元素之前指定哪些元素是 non-zero。这是通过将索引作为 (int, int)
元组(或 (int, int)
元组的数组)添加到稀疏域来完成的。
下面是一个生成 100x100 压缩稀疏行 (CSR) 数组的小示例,其中包含 10 个 non-zero 个随机元素:
/* Example tested with Chapel 1.22 */
import LayoutCS.{CS, isCSType};
import Random;
/* Parent domain dimensions: NxN */
config const N = 100;
/* Number of non-zero elements */
config const nnz = 10;
const parentDom = {1..N, 1..N};
var csrDom: sparse subdomain(parentDom) dmapped CS();
var A: [csrDom] real;
populate(A, csrDom, nnz);
// Print non-zero elements
for (i,j) in csrDom do
writeln((i,j), ':', A[i, j]);
/* Populate sparse matrix with `nnz` random values */
proc populate(ref A, ref ADom, nnz: int) where isCSType(ADom.dist.type) && isCSType(A.domain.dist.type) {
// Generate array of random non-zero indices
var indices: [1..nnz] 2*int;
var randomIndices = Random.createRandomStream(eltType=int);
// Replace any duplicate indices with a new random index
for idx in indices {
var newIdx = idx;
while indices.find(newIdx)(1) {
newIdx = (randomIndices.getNext(ADom.dim(0).low, ADom.dim(0).high),
randomIndices.getNext(ADom.dim(1).low, ADom.dim(1).high));
}
idx = newIdx;
}
// Add the non-zero indices to the CSR domain
ADom += indices;
// Generate random elements - maybe fillRandom(A) could do this for us some day
var randomElements = Random.createRandomStream(eltType=A.eltType);
for idx in ADom {
A[idx] = randomElements.getNext();
}
}