构建教堂稀疏热带限制函数

时间:2018-03-21 22:39:29

标签: graph sparse-matrix hpc convergence chapel

鉴于矩阵AB,热带产品被定义为通常的矩阵乘积,其中乘法交易用于minimum的追加和追加。也就是说,它返回一个新的矩阵C,使其

C_ij = minimum(A_ij, B_ij, A_i1 + B_1j, A_i2 + B_12,..., A_im + B_mj)

给定图A_g的基础邻接矩阵gnth&#34; power&#34;相对于热带产品,表示最多n步骤中可达到的节点之间的连接。也就是说,如果节点C_ij = (A**n)_ijmi边分开,则j的值为m<=n

一般情况下,给定一些带有N个节点的图表。图表的直径最多只能为N;并且,给定一个直径为k的图表,A**n = A**k为所有n>k,矩阵D_ij = A**k称为&#34;距离矩阵&#34;表示图中所有节点之间距离的条目。

我在小教堂写了一个热带产品函数,我想写一个函数,它接受一个邻接矩阵并返回结果距离矩阵。我尝试了以下方法无济于事。我们将非常感谢您对这些错误的指导!

proc tropicLimit(A:[] real,B:[] real) {
 var R = tropic(A,B);
 if A == R {
   return A;
 } else {
   tropicLimit(R,B);
 }
}

引发了域名不匹配错误,因此我进行了以下编辑:

proc tropicLimit(A:[] real,B:[] real) {
 var R = tropic(A,B);
 if A.domain == R.domain {
   if && reduce (A == R) {
     return R;
   } else {
     tropicLimit(R,B);
   }
 } else {
   tropicLimit(R,B);
 }
}

抛出

src/MatrixOps.chpl:602: error: control reaches end of function that returns a value

proc tropicLimit(A:[] real,B:[] real) {
 var R = tropic(A,B);
 if A.domain == R.domain {
   if && reduce (A == R) {  // Line 605 is this one
   } else {
     tropicLimit(R,B);
   }
 } else {
   tropicLimit(R,B);
 }
return R;
}

让我回到这个错误

src/MatrixOps.chpl:605: error: halt reached - Sparse arrays can't be zippered with anything other than their domains and sibling arrays (CS layout)

我也尝试使用for循环,break条件,但不起作用

proc tropicLimit(B:[] real) {
 var R = tropic(B,B);
 for n in B.domain.dim(2) {
   var S = tropic(R,B);
   if S.domain != R.domain {
    R = S; // Intended to just reassign the handle "R" to the contents of "S" i.o.w. destructive update of R
   } else {
     break;
   }   
 }
 return R;
}

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

  

src / MatrixOps.chpl:605:错误:停止到达 - 稀疏数组不能用其他域和兄弟阵列(CS布局)拉链拉

我相信您在当前实现中遇到了拉链稀疏数组的限制,在#6577中有记录。

从等式中删除一些未知数,我相信这个已提炼的代码段演示了您遇到的问题:

use LayoutCS;

var dom = {1..10, 1..10};

var Adom: sparse subdomain(dom) dmapped CS();
var Bdom: sparse subdomain(dom) dmapped CS();

var A: [Adom] real;
var B: [Bdom] real;

Adom += (1,1);
Bdom += (1,1);

A[1,1] = 1.0;
B[1,1] = 2.0;


writeln(A.domain == B.domain); // true
var willThisWork = && reduce (A == B);
// dang.chpl:19: error: halt reached - Sparse arrays can't be zippered with
//           anything other than their domains and sibling arrays (CS layout)

作为解决方法,我建议在确认域相等并执行&& reduce之后循环遍历稀疏索引。这可以包装在辅助函数中,例如

proc main() { 
  var dom = {1..10, 1..10};

  var Adom: sparse subdomain(dom) dmapped CS();
  var Bdom: sparse subdomain(dom) dmapped CS();

  var A: [Adom] real;
  var B: [Bdom] real;

  Adom += (1,1);
  Bdom += (1,1);

  A[1,1] = 1.0;
  B[1,1] = 2.0;

  if A.domain == B.domain {
    writeln(equal(A, B));
  }
}

/* Some day, this should be A.equals(B) ! */
proc equal(A: [], B: []) {
  // You could also return 'false' if domains do not match
  assert(A.domain == B.domain);

  var s = true;

  forall (i,j) in A.domain with (&& reduce s) {
    s &&= (A[i,j] == B[i,j]);
  }

  return s;
}
  

src / MatrixOps.chpl:602:错误:控件到达返回值的函数的结尾

此错误是由于未在每种情况下都返回某些内容而导致的。我相信你打算这样做:

proc tropicLimit(A:[] real,B:[] real) {
 var R = tropic(A,B);
 if A.domain == R.domain {
   if && reduce (A == R) {
     return R;
   } else {
     return tropicLimit(R,B);
   }
 } else {
   return tropicLimit(R,B);
 }
}