来自一组二维数组的意外类型

时间:2017-06-06 02:27:30

标签: arrays types slice chapel

在下面的代码中,我试图使用Avar来获取数组ref的第1行和第2行。在此,我的理解是var始终创建一个新数组,而ref创建一个右侧的别名(或引用)。

var A: [1..2, 1..3] int;
A = 0;

var row1 = A[ 1, .. ];
ref row2 = A[ 2, .. ];

row1 = 10;
row2 = 20;

writeln( "row1 = ", row1 );
writeln( "row2 = ", row2 );

writeln( "A = ", A );

结果与预期一致(即A的第一行未被修改):

row1 = 10 10 10
row2 = 20 20 20
A = 0 0 0
20 20 20

但是,如果我打印row1row2

的类型
writeln( "row1.type = ", row1.type: string );
writeln( "row2.type = ", row2.type: string );

我得到了这个结果:

row1.type = [ArrayViewRankChangeDom(1,int(64),false,2*bool,2*int(64),ArrayViewRankChangeDist(DefaultDist,2*bool,2*int(64)))] int(64)
row2.type = [ArrayViewRankChangeDom(1,int(64),false,2*bool,2*int(64),ArrayViewRankChangeDist(DefaultDist,2*bool,2*int(64)))] int(64)

这有点令人惊讶,因为我认为row1是一个“通常”的数组(即,不是别名)。例如,以下vec(我称之为“通常”数组)

var vec: [1..3] int;
writeln( "vec.type = ", vec.type: string ); 

给出

vec.type = [domain(1,int(64),false)] int(64)

所以我想知道row1vec之间是否存在差异(作为数组类型)......?

1 个答案:

答案 0 :(得分:2)

  

我想知道row1和vec(作为数组类型)之间是否有一些区别......?

虽然你是否认为它的类型差异在某种程度上取决于你的类型概念,但存在差异。每个Chapel数组都是根据域映射定义的,该映射指定了它的定义方式(以及如何定义其域)。如果未指定域映射,则使用默认域映射。数组的域映射在技术上是其类型的一部分,但在实践中,它往往是一个应该影响数组实现方式的方面,而不是可以应用于数组的操作。

因此,您的示例中的vec是由int(64) s索引的int(64)元素的一维数组(并且其索引是非标记的,这是false中的A[i, ..]域的签名代表),其域映射是默认的域映射。同时,切片表达式int(64)也是由int(64)索引的ArrayViewRankChange元素的一维数组(并且也是非强制的),但它们的域映射是ArrayViewRankChange。这是一个内部域映射,表示另一个数组的排名更改别名(“view”)。

[使用这个不同的域映射来表示数组的排名更改切片的基本原理的简短版本是这样的:如果原始的2D数组是分布的(比方说),它的1D切片应该可能是类似的分布同样 - 这表明它不应该是默认的域映射(不是分布式的),也不应该是原始数组的分布(它描述了如何实现2D事物)。所以选择要么是要求排名切片需要域映射来创建自己的新的低维域映射(这往往介于挑战性和不可能之间),要么使用知道如何从1D索引转换的新域映射到原始分布的2D指数。这就是row2域映射的作用。从幻灯片27(“数组视图”)开始的1.15 release notes中可以找到更长版本的基本原理。]

鉴于上述情况,ArrayViewRankChange也可能表示row1作为其域映射,因为它是对秩变更切片表达式的引用。但ArrayViewRankChange可能更令人惊讶,因为它是一个全新的数组,导致ArrayViewRankChange数组的深层副本,因此可以使用传统的默认数组存储。但是在分布式案例中可以再次看到基本原理,即新的数组变量应该(可能)与原始变量具有相同的分布 - 我们这样做的方法是通过var row1b: [A.domain.dim(2)] A.eltType = A[1, ..];

如果要强制数组切片为“普通数组”,可以使用更精确的声明来实现:

vec

此时其类型将匹配row1b.type = [domain(1,int(64),false)] int(64) s:

row1

所有这一切,希望您会发现在大多数可以使用row2的地方都可以使用vec--- title: "Untitled" runtime: shiny output: html_document --- ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE) ``` ```{r} df <- data.frame(image = "http://www.ufotm.com/data/attachment/forum/201203/11/110705gf50r55yqcka5ffz.jpg", title = "here is a title") DT::renderDataTable(df, escape = FALSE, rownames = FALSE, extensions = 'Buttons', options = list( dom = 'lBfrtip', buttons = c('copy', 'csv', 'excel', 'pdf', 'print') ) ) ``` 。如果没有,请询​​问后续问题或在GitHub上提出问题。

作为结束语,可以说编译器可以/应该更好地打印数组类型,或者至少为打印出类型提供不同的冗余级别选项(例如,在许多情况下,也许识别域映射是不必要的,或者可能更简单地打印域类型?)