ROSE 声明CUDA类型的变量

问题

需要声明CUDA类型的变量,如 constant,device,shared等等

解决方案

调用get_declarationModifier().get_storageModifier().set

ROSE 创建模板类变量的一个取巧办法

问题

用ROSE产生cuda代码时,为了性能需要,使用到了纹理存储器。但在纹理存储器变量声明的时候,遇到了点问题:纹理寄存器变量的类型是模板类实例,e.g,texture<DATATYPE,1,cudaReadModeElementType> t_a,但是rose中模板类变量貌似不怎么好声明,尝试了半天都没有成功。

解决方案

使用万金油式的buildOpaqueType直接创建模板类型,然后使用该类型创建纹理存储器变量

1
2
3
4
5
//create a template instance type directly: texture<DATATYPE,1,cudaReadModelElementType>
SgType* textureType=buildOpaqueType("texture<DATATYPE,1,cudaReadModelElementType>",node->get_scope());

//create the texture type variable "texture_a"
SgVariableDeclaration* vdecl=buildVariableDeclaration("texture_a",textureType,node->get_scope());

Error: No Instance of Overloaded Function "tex1Dfetch" Matches the Argument List Argument Types Are: (Texture, Int)

问题

在使用cuda的纹理存储器时,编译器报错

1
2
3
4
stencilexample.cu(147): error:
no instance of overloaded function "tex1Dfetch"
matches the argument list argument types are:
(texture<double, 1, cudaReadModeElementType>, int)

解决方法

经过研究,发现原来cuda的纹理存储器不能直接支持double

The type of a texel, which is restricted to the basic integer and single-precision floating-point types and any of the 1-, 2-, and 4-component vector types defined in char, short, int, long, longlong, float, double that are derived from the basic integer and single-precision floating-point types. 出处:cuda-c-programming-guide

非要加速的话,可以使用一个int2类型的向量拼接成一个double

1
2
3
4
5
6
7
//declarate the texture using int2 type
texture <int2,1,cudaReadModeElementType> Atex;


//used in global function(cuda kernel)
int2 A1=tex1Dfetch(Atex,(texoff+(ll+offset) *lda +ty+offset));
Bs[ty+offset][tx] -= __hiloint2double(A1.y,A1.x)*temp;

R 字符操作函数

函数 描述
nchar(x) 计算x中的字符数量
substr(x, start, stop) 字符串截取
grep(pattern, x) 字符串内的查找
paste(…, sep = “ ”, collapse = NULL) 字符串连接
strsplit(x, split) 字符串分割
tolower() 把x变成小写
toupper(x) 把x变成大写
casefold(x, upper = FALSE) 通过指定upper,把x变成大写或者小写
chartr(old, new, x) 把x中每个在old中出现的字符翻译成new中相应位置的字符

R语言 使用循环构建dataframe

  • 目前有个模块需要动态的确定dataframe的属性和值,属性和值以key=value的形式存在一个str 的list中,使用如下函数循环构建dataframe
1
2
3
4
5
6
7
8
9
10
11
 for(item in dataItems)
  {
    itempair <- unlist(strsplit(item, "="))
    eval(parse(text=sprintf("%s=itempair[2]",itempair[1])))
    if(datadf_str!="")
      datadf_str=paste(datadf_str,itempair[1],sep=",")
    else
      datadf_str=itempair[1]
    print(datadf_str)
  }
  datadf=eval(parse(text=sprintf("data.frame(%s)",datadf_str)))

R语言 变量

对全局变量的赋值

  1. 在函数外部:
    • global_variable<-newvalue
    • global_variable=newvalue
  2. 在函数内部:
    • global_variable<<-newvalue

R语言 行与列的操作

选择列

数据框/dataframe:

引用:

  • dn、d[,n]、d"name"、d[,“name”]、d$name 得到某一列组成的矢量。
  • d[n]、d[“name”] 得到某一列组成的数据框。
  • d[c(m,n,…)]、d[,c(m,n,…)]、d[,c(“name1”,“name2”,…)]得到若干列组成的数据框。

    其它技巧:

  • 负号表示剔除。
1
2
3
4
  allnames=names(rawdata)
  vnames=c("OptType","OptConfig","Gflops")
  vnames2=allnames %in% vnames
  snames=allnames[!vnames2]
  • 可以用 grep() 搜索变量名。比如 mydata[grep("^q", names(mydata))] 选择名称以“q”开头的数据列。

列表/List:

list列的引用

  • d[[“colname”]] 得到成分名为colname的列矢量

选择行

数据框:

引用:

  • d[n,] 得到某一行组成的数据框。
  • d[c(m,n,…),n] 得到若干行组成的数据框。
  • head() 得到前6行组成的数据框。
  • tail() 得到最后6行组成的数据框。

条件引用。例如:

  • d[d$y>8,] 得到d中满足y>8的行组成的数据框。
  • d$x[d$y>8] 得到d中满足y>8的行的列x组成的矢量。

数据框行的遍历

  • 使用索引进行遍历
1
2
for(i in 1:nrow(rawdata))
  dosomething(rawdata[i,])

A Rose Problem: SgNode::get_numberOfTraversalSuccessors(): Assertion 'False' Failed

问题

1
2
3
4
5
6
Internal error(!): called tree traversal mechanism for illegal object:
static: SgNode
dynamic:  SgNode
Aborting ...
my_program: Cxx_GrammarTreeTraversalSuccessorContainer.C:42: virtual
size_t SgNode::get_numberOfTraversalSuccessors(): Assertion `false' failed.

解决方法

这种错误一般是由于语法树具有环路造成的。造成环路的原因一般是因为一个astnode被多次使用,解决方法是利用deepcopy在多次使用的地方克隆。

TAU 中的profile和trace

预备知识

  • profile侧重结果,trace侧重过程。

  • 对于两个不同类型的测试(profile or trace),需要指定不同的makefile文件,各类makefile文件在tau编译配置时根据参数指定生成。

自动化插桩的过程:

  • 添加或者设需要的makefile

  • 根据待插桩的源码,设置相应的tau编译器(可在makefile中替换或者直接使用tau编译器编译)

例子:

1
2
3
4
5
6
7
8
9
10
11
12
#设置tau makefile
export TAU_MAKEFILE=/home/xxxx/tools/tau_TRACE_PAPIWALLCLOCK/x86_64/lib/Makefile.tau-papi-pdt-trace

#设置插桩参数
export TAU_THROTTLE=0
export COUNTER1=P_WALL_CLOCK_TIME
export COUNTER2=PAPI_L1_DCM
export COUNTER3=PAPI_FP_INS

#调用tau编译器
tau_f90.sh  -c  hps_em_comp.f90
tau_cxx.sh  main.cpp  hps_em_comp.o -o mytest
  • 此外,进一步的详细插桩可以通过在编译时指定配置文件
1
tau_f90.sh -tau_options=-optTauSelectFile=ins_file -c  hps_em_comp.f90
  • 配置文件格式如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#Tell tau to not profile these functions
BEGIN_EXCLUDE_LIST
double* get(int size)
END_EXCLUDE_LIST

#Exclude these files from profiling

BEGIN_FILE_EXCLUDE_LIST
*.so
END_FILE_EXCLUDE_LIST

BEGIN_INSTRUMENT_SECTION
#插桩所有在文件loop_test.cpp中函数multiply内的循环
loops file="loop_test.cpp" routine="multiply"
#插入代码段

file = "line_test.cpp" line = 9 code = "printf(\"i=%d: \", i);"
exit routine ="int foo()" code = "cout <<\"exiting foo\"<<endl;"
entry routine ="int foo()" code = "cout <<\"entering foo\"<<endl;i"
END_INSTRUMENT_SECTION
  • 使用PAPI测量更多指标,首先下指定使用papi参数编译的tau ,makefile,其次,使用环境变量PAPI_EVENT

  • 当一次要采集多个指标时,可以通过设置COUNT <1-25>来实现

1
2
3
export COUNTER1=P_WALL_CLOCK_TIME
export COUNTER2=PAPI_L1_DCM
export COUNTER3=PAPI_FP_INS
  • 之后用paraprof –pack 命令打包结果成ppk,上传至数据库。
1
paraprof --pack pdata.ppk