Nek5000
SEM for Incompressible NS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
fcrystal.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stddef.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include "c99.h"
6 #include "name.h"
7 #include "fail.h"
8 #include "types.h"
9 #include "mem.h"
10 #include "comm.h"
11 #include "crystal.h"
12 #include "sort.h"
13 #include "sarray_sort.h"
14 #include "sarray_transfer.h"
15 
16 /*--------------------------------------------------------------------------
17 
18  FORTRAN Interface to crystal router
19 
20  integer h, np
21  MPI_Comm comm
22  call crystal_setup(h,comm,np) ! set h to handle to new instance
23  ! it is a runtime error if MPI_Comm_size gives a value different than np
24  call crystal_free(h) ! release instance
25 
26  integer*? ituple(m,max) ! integer type matching sint from "types.h"
27  call crystal_ituple_transfer(h, ituple,m,n,max, kp)
28  - moves each column ituple(:,i), 1 <= i <= n,
29  to proc ituple(kp,i)
30  - sets n to the number of columns received,
31  which may be larger than max (indicating loss of n-max columns)
32  - also sets ituple(kp,i) to the source proc of column ituple(:,i)
33 
34  call crystal_ituple_sort(h, ituple,m,n, key,nkey)
35  - locally sorts columns ituple(:,1...n) in ascending order,
36  ranked by ituple(key(1),i),
37  then ituple(key(2),i),
38  ...
39  then ituple(key(nkey),i)
40  - no communication; h used for scratch area
41  - linear time
42  - assumes nonnegative integers
43 
44  integer*? vi(mi,max) ! integer type matching sint from "types.h"
45  integer*? vl(ml,max) ! integer type matching slong from "types.h"
46  real vr(mr,max)
47  call crystal_tuple_transfer(h,n,max, vi,mi,vl,ml,vr,mr, kp)
48  - moves each column vi(:,i),vl(:,i),vr(:,i) 1 <= i <= n,
49  to proc vi(kp,i)
50  - sets n to the number of columns received,
51  which may be larger than max (indicating loss of n-max columns)
52  - also sets vi(kp,i) to the source proc of columns vi(:,i),vl(:,i),vr(:,i)
53 
54  call crystal_tuple_sort(h,n, vi,mi,vl,ml,vr,mr, key,nkey)
55  - locally sorts columns vi/vl/vr (:,1...n) in ascending order,
56  ranked by vi(key(1),i) [ or vl(key(1)-mi,i) if key(1)>mi ],
57  then vi(key(2),i) [ or vl(key(2)-mi,i) if key(2)>mi ],
58  ...
59  then vi(key(nkey),i) or vl(key(nkey)-mi,i)
60  - no communication; h used for scratch area
61  - linear time
62  - assumes nonnegative integers
63  - sorting on reals not yet implemented
64 
65  --------------------------------------------------------------------------*/
66 
67 #undef crystal_free
68 #define ccrystal_free PREFIXED_NAME(crystal_free)
69 
70 #define fcrystal_setup \
71  FORTRAN_NAME(crystal_setup ,CRYSTAL_SETUP )
72 #define fcrystal_ituple_sort \
73  FORTRAN_NAME(crystal_ituple_sort ,CRYSTAL_ITUPLE_SORT )
74 #define fcrystal_tuple_sort \
75  FORTRAN_NAME(crystal_tuple_sort ,CRYSTAL_TUPLE_SORT )
76 #define fcrystal_ituple_transfer \
77  FORTRAN_NAME(crystal_ituple_transfer,CRYSTAL_ITUPLE_TRANSFER)
78 #define fcrystal_tuple_transfer \
79  FORTRAN_NAME(crystal_tuple_transfer ,CRYSTAL_TUPLE_TRANSFER )
80 #define fcrystal_free \
81  FORTRAN_NAME(crystal_free ,CRYSTAL_FREE )
82 
83 static struct crystal **handle_array = 0;
84 static int handle_max = 0;
85 static int handle_n = 0;
86 
87 void fcrystal_setup(sint *handle, const MPI_Fint *comm, const sint *np)
88 {
89  struct crystal *p;
90  if(handle_n==handle_max)
92  handle_array=trealloc(struct crystal*,handle_array,handle_max);
93  handle_array[handle_n]=p=tmalloc(struct crystal,1);
94  comm_init_check(&p->comm, *comm, *np);
95  buffer_init(&p->data,1000);
96  buffer_init(&p->work,1000);
97  *handle = handle_n++;
98 }
99 
100 #define CHECK_HANDLE(func) do \
101  if(*handle<0 || *handle>=handle_n || !handle_array[*handle]) \
102  fail(1,__FILE__,__LINE__,func ": invalid handle"); \
103 while(0)
104 
106  sint A[], const sint *m, const sint *n,
107  const sint keys[], const sint *nkey)
108 {
109  const size_t size = (*m)*sizeof(sint);
110  sint nk = *nkey;
111  buffer *buf;
112  CHECK_HANDLE("crystal_ituple_sort");
113  buf = &handle_array[*handle]->data;
114  if(--nk>=0) {
115  sortp(buf,0, (uint*)&A[keys[nk]-1],*n,size);
116  while(--nk>=0)
117  sortp(buf,1, (uint*)&A[keys[nk]-1],*n,size);
118  sarray_permute_buf_(ALIGNOF(sint),size,A,*n, buf);
119  }
120 }
121 
122 void fcrystal_tuple_sort(const sint *const handle, const sint *const n,
123  sint Ai[], const sint *const mi,
124  slong Al[], const sint *const ml,
125  double Ad[], const sint *const md,
126  const sint keys[], const sint *const nkey)
127 {
128  const size_t size_i = (*mi)*sizeof(sint),
129  size_l = (*ml)*sizeof(slong),
130  size_d = (*md)*sizeof(double);
131  int init=0;
132  sint nk = *nkey;
133  buffer *buf;
134  CHECK_HANDLE("crystal_tuple_sort");
135  buf = &handle_array[*handle]->data;
136  if(nk<=0) return;
137  while(--nk>=0) {
138  sint k = keys[nk]-1;
139  if(k<0 || k>=*mi+*ml)
140  fail(1,__FILE__,__LINE__,"crystal_tuple_sort: invalid key");
141  else if(k<*mi) sortp (buf,init, (uint *)&Ai[k], *n,size_i);
142  else sortp_long(buf,init, (ulong*)&Al[k-*mi],*n,size_l);
143  init=1;
144  }
145  if(*mi) sarray_permute_buf_(ALIGNOF(sint ),size_i,Ai,*n, buf);
146  if(*ml) sarray_permute_buf_(ALIGNOF(slong ),size_l,Al,*n, buf);
147  if(*md) sarray_permute_buf_(ALIGNOF(double),size_d,Ad,*n, buf);
148 }
149 
151  sint A[], const sint *m, sint *n,
152  const sint *nmax, const sint *proc_key)
153 {
154  struct array ar, *const ar_ptr = &ar;
155  const unsigned size=(*m)*sizeof(sint);
156  CHECK_HANDLE("crystal_ituple_transfer");
157  ar.ptr=A, ar.n=*n, ar.max=*nmax;
158  *n = sarray_transfer_many(&ar_ptr,&size,1, 1,0,1,(*proc_key-1)*sizeof(sint),
159  (uint*)&A[*proc_key-1],size, handle_array[*handle]);
160 }
161 
163  const sint *const handle, sint *const n, const sint *const max,
164  sint Ai[], const sint *const mi,
165  slong Al[], const sint *const ml,
166  double Ad[], const sint *const md,
167  const sint *const proc_key)
168 {
169  struct array ar_i, ar_l, ar_d, *ar[3];
170  unsigned size[3];
171  CHECK_HANDLE("crystal_tuple_transfer");
172  size[0]=*mi*sizeof(sint);
173  size[1]=*ml*sizeof(slong);
174  size[2]=*md*sizeof(double);
175  ar[0]=&ar_i, ar[1]=&ar_l, ar[2]=&ar_d;
176  ar_i.ptr=Ai,ar_l.ptr=Al,ar_d.ptr=Ad;
177  ar_i.n=ar_l.n=ar_d.n = *n;
178  ar_i.max=ar_l.max=ar_d.max=*max;
179  *n = sarray_transfer_many(ar,size,3, 1,0,1,(*proc_key-1)*sizeof(sint),
180  (uint*)&Ai[*proc_key-1],size[0], handle_array[*handle]);
181 }
182 
184 {
185  CHECK_HANDLE("crystal_free");
186  ccrystal_free(handle_array[*handle]);
187  free(handle_array[*handle]);
188  handle_array[*handle] = 0;
189 }
190 
191 
#define slong
Definition: types.h:74
#define uint
Definition: types.h:70
size_t n
Definition: mem.h:111
#define tmalloc(type, count)
Definition: mem.h:91
#define sint
Definition: types.h:69
#define fcrystal_tuple_sort
Definition: fcrystal.c:74
buffer work
Definition: crystal.c:52
n
Definition: xxt_test.m:73
#define sarray_permute_buf_
Definition: sarray_sort.c:12
#define fcrystal_ituple_sort
Definition: fcrystal.c:72
#define trealloc(type, ptr, count)
Definition: mem.h:95
ulong A[NUM][SI]
Definition: sort_test.c:17
Definition: comm.h:85
static int handle_max
Definition: fcrystal.c:84
buffer data
Definition: crystal.c:52
#define fcrystal_setup
Definition: fcrystal.c:70
const uint Ai[3][32]
Definition: xxt_test.c:80
p
Definition: xxt_test2.m:1
#define comm_init_check(c, ce, np)
Definition: comm.h:161
Definition: mem.h:111
size_t max
Definition: mem.h:111
#define ulong
Definition: types.h:75
#define fcrystal_ituple_transfer
Definition: fcrystal.c:76
#define sarray_transfer_many
static struct crystal ** handle_array
Definition: fcrystal.c:83
#define sortp_long
Definition: sort.h:57
uint * sortp(buffer *restrict buf, int start_perm, const T *restrict A, uint n, unsigned stride)
Definition: sort_imp.h:477
#define ALIGNOF(T)
Definition: mem.h:163
#define ccrystal_free
Definition: fcrystal.c:68
void * ptr
Definition: mem.h:111
#define fcrystal_tuple_transfer
Definition: fcrystal.c:78
#define buffer_init(b, max)
Definition: mem.h:155
int MPI_Fint
Definition: comm.h:71
#define CHECK_HANDLE(func)
Definition: fcrystal.c:100
establishes some macros to establish naming conventions
static uint np
Definition: findpts_test.c:63
#define fcrystal_free
Definition: fcrystal.c:80
static int handle_n
Definition: fcrystal.c:85
struct comm comm
Definition: crystal.c:51
void fail(int status, const char *file, unsigned line, const char *fmt,...)
Definition: fail.c:47