首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Unified Parallel C 中的集体函数-2

Unified Parallel C 中的集体函数-2

清单 5
下面程序通过 upc_all_exchange 对共享数组 A 进行按照函数定义的顺序进行转置,并将结果数组复制到共享数组 B 中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# include <upc.h>
# include <upc_collective.h>
# include <stdio.h>
# define NELEMS 3
# define FAILURE 1
# define SUCCESS 0
shared[NELEMS*THREADS] int A[THREADS][NELEMS*THREADS];
shared[NELEMS*THREADS] int B[THREADS][NELEMS*THREADS];
int main()
{
  int i=0,j=0;

  // 对 A 进行初始化
  for(i=0;i<NELEMS*THREADS;i++)
  A[MYTHREAD]=1;
  upc_barrier;
  upc_all_exchange(B,A,sizeof(int)*NELEMS,UPC_IN_NOSYNC|UPC_OUT_NOSYNC);
  upc_barrier;

  // 校验结果
  for(i=0;i<NELEMS*THREADS;i++)
  {
    if(B[MYTHREAD] != 1)
    {
      printf("Error: thread=%d,result=%d,expect=%d\n",MYTHREAD,B[MYTHREAD],1);
      upc_global_exit(FAILURE);
    }
  }
  return SUCCESS;
}




upc_all_permute
作用:从与第 i 个线程具有亲缘关系的共享内存里,复制一块内存到与线程 perm具有亲缘关系的一块内存。
原型:
1
2
void upc_all_permute(shared void * restrict dst, shared const void * restrict src, \
shared const int * restrict perm, size_t nbytes, upc_flag_t flags);




参数:
dst:一个指向内存复制目标地址的指针。
src:一个指向要被复制数据地址的指针。
perm:一个指向与线程 0 具有亲缘关系的共享数据的指针。
nbytes:代表所要复制数据块大小为多少字节。
flags:控制函数的同步模式。
清单 6
下面程序通过 upc_all_permute 将共享数组 A 中的元素区块,根据 P 数组中所提供的亲缘关系数据,相应地复制到共享数组 B 中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# include <upc.h>
# include <upc_collective.h>
# include <stdio.h>
# define NELEMS 10
# define FAILURE 1
# define SUCCESS 0

shared[NELEMS] int A[NELEMS*THREADS]; // src 指针
shared[NELEMS] int B[NELEMS*THREADS]; // dst 指针
shared int P[THREADS];
shared[] int *myB;

int main()
{
  int i=0,j=0;

  // 对 P 进行初始化
  P[MYTHREAD]=THREADS-1-MYTHREAD;

  // 对 A 进行初始化
  upc_forall(i=0;i<NELEMS*THREADS;i++;&A)
  A=i;
  upc_barrier;
  upc_all_permute(B,A,P,sizeof(int)*NELEMS,UPC_IN_NOSYNC|UPC_OUT_NOSYNC);
  upc_barrier;

  // myB 为对应的线程指向数组的第一个元素
  myB=(shared[] int *)&B[MYTHREAD*NELEMS];

  // 校验结果
  for(i=0;i<NELEMS;i++)
  if(myB != (THREADS-1-MYTHREAD)*NELEMS+i)
  {
    printf("Error: thread:%d, myB[%d]=%d,expect=%d\n",MYTHREAD,i,myB, (THREADS-1-
    MYTHREAD)*NELEMS+i);
    upc_global_exit(FAILURE);
  }
  return SUCCESS;
}




数据计算集体函数作用:对所有元素进行用户自定义的操作。
原型:
1
2
3
4
void upc_all_reduceT(shared void * restrict dst, shared const void * restrict src,
upc_op_t op, \size_t nelems, size_t blk_size, TYPE(*func)(TYPE, TYPE), upc_flag_t flags);
void upc_all_prefix_reduceT(shared void * restrict dst, shared const void * restrict src,
upc_op_t op, \size_t nelems, size_t blk_size, TYPE(*func)(TYPE, TYPE), upc_flag_t flags);




参数:
dst:指向存储计算操作结果的共享数组的指针。
src:指向要进行计算操作的共享数组的指针。
op :指定对数组元素要进行的计算操作。
nelems:代表每个共享数组里的元素个数。
blk_size:代表一个内存块大小的字节数。
func:指向对数组元素进行用户自定义操作的函数的指针。
flags:控制数据同步的方式。
下面程序通过函数 upc_all_reduceT 对共享数组 srcA 中的数据进行加法操作,并将结果存在共享数组 srcB 中。
清单 7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# include <upc.h>
# include <upc_collective.h>
# include <stdio.h>
# define SUCCESS 0
# define FAILURE 1
# define BLKSIZE1 5
# define BLKSIZE2 0
# define N 100
# define verify(result,expect) \
{ if ((result)!=(expect)) \
{ \
printf("Error: fail at line %d: mythread=%d, result= %d, expect= %d\n",
__LINE__, MYTHREAD, result,expect); \
upc_global_exit(FAILURE); \
} \
}
typedef int T; //T 的类型是整形
shared[BLKSIZE1] T srcA[N];
shared[BLKSIZE2] T srcB[N];
shared T *dst;
shared T result;
int main()
{
  int i,j;

  // 初始化共享数组
  upc_forall(i=0; i<N; i++; &srcA)
  srcA=i;
  upc_forall(i=0;i<N;i++;&srcB)
  srcB=-i;
  upc_barrier;

  // 初始化 dst 指针
  dst=&result;
  /* dst 指针访问的共享数据的值为 srcA[0] + srcA[1] + srcA[N-1], 其中 0<= i <=N-1, + 是变量所指定的
  运算符*/

  upc_all_reduceI(dst,srcA,UPC_ADD,N,BLKSIZE1,NULL,UPC_IN_NOSYNC | UPC_OUT_NOSYNC);
  upc_barrier;

  // 校验结果
  verify(*dst,(N - 1)*N/2);
  verify(result,(N - 1)*N/2);
  upc_barrier;

  /* dst 指针所指向共享数据的值为 srcB[0] + srcB[1] + srcB[N-1],其中 0<= i <=N-1, + 是变量指定的运
  算符*/
  upc_all_reduceI(dst,srcB,UPC_ADD,N,BLKSIZE2,NULL,UPC_IN_NOSYNC | UPC_OUT_NOSYNC);
  upc_barrier;

  // 校验结果
  verify(*dst,-1*(N - 1)*N/2);
  verify(result,-1*(N - 1)*N/2);
  return SUCCESS;
}




清单 8
下面程序通过函数 upc_all_prefix_reduceL 对共享数组 srcA 中的数据进行加法操作,并将结果存在共享数组 srcB 中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# include <upc.h>
# include <upc_collective.h>
# include <stdio.h>
# define SUCCESS 0
# define FAILURE 1
# define BLKSIZE1 5
# define BLKSIZE2 0
# define N 100
# define verify(result,expect) \
{ if ((result)!=(expect)) \
{ \
printf("Error: fail at line %d: mythread=%d, result= %l, expect= %l\n",
__LINE__, MYTHREAD, result,expect); \
upc_global_exit(FAILURE); \
} \
}
typedef long T; // T 类型是一个长整型
shared[BLKSIZE1] T srcA[N];
shared[BLKSIZE2] T srcB[N];
shared[BLKSIZE1] T dstA[N];
shared[BLKSIZE2] T dstB[N];

int main()
{
  int i;
  // 初始化 srcA 与 srcB
  upc_forall(i=0;i<N;i++;&srcA)
  srcA=i;
  upc_forall(i=0;i<N;i++;&srcB)
  srcB=-i;
  upc_barrier;

  /* 函数要求 upc_threadof(srcA) == upc_threadof(dstA) && upc_phaseof(srcA) ==
   upc_phaseof(dstA), dstA所指向的共享数据的值为 srcA[0] + srcA[1] + ... + srcA, 其中 0<=
   i <=N-1, + 是指定的运算符*/
  upc_all_prefix_reduceL(dstA,srcA,UPC_ADD,N,BLKSIZE1,NULL,UPC_IN_NOSYNC | UPC_OUT_NOSYNC);
  upc_barrier;

  // 校验结果
  for(i=0;i<N;i++)
  verify(dstA,i*(i+1)/2);

  /* 函数要求 upc_threadof(srcB) == upc_threadof(dstB) && upc_phaseof(srcB) ==
  upc_phaseof(dstB), dstB指针所指向的共享数据的值为 srcB[0] + srcB[1] + ... + srcB,
  其中 0<=  i <=N-1, + 是函数指定的运算符*/
  upc_all_prefix_reduceL(dstB,srcB,UPC_ADD,N,BLKSIZE2,NULL,UPC_IN_ALLSYNC |
  UPC_OUT_ALLSYNC);

  //校验结果
  for(i=0;i<N;i++)
  verify(dstB,-i*(i+1)/2);
  return SUCCESS;
}

返回列表