-
Notifications
You must be signed in to change notification settings - Fork 3
/
gen_F95_wrapper_subs.pl
executable file
·155 lines (136 loc) · 4.92 KB
/
gen_F95_wrapper_subs.pl
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/perl
use warnings;
use strict;
=pod
This script generates specialised subroutines for a set of array dimensions, types and access modes because Fortran is not polymorphic.
The generated subroutines are
oclMake${dim}D${type}Array${mode}Buffer
oclWrite${dim}D${type}ArrayBuffer
oclRead${dim}D${type}ArrayBuffer
=cut
# Dimensions
my @dims = (1..7); # Fortran arrays are limited to 7 dimensions
# Types
my @types = qw(Float Double Int Long);
# Modes
my @modes = qw(Read Write ReadWrite);
my %ftypes =(Float => 'real', Int => 'integer', Double => 'real(8)', Long => 'integer(8)');
my %wordsizes = (Float => 4, Double => 8, Int => 4, Long => 8);
sub gen_szstr {
my $dim=shift;
my @insts = map {"sz($_)" } (1..$dim);
my $szstr=join(', ',@insts);
return $szstr;
}
open my $IN, '<', 'oclWrapper_TEMPL.f95';
open my $OUT, '>', 'oclWrapper.f95';
print $OUT "!!! Don't edit this file!!! Edit oclWrapper_TEMPL.f95 and run $0 !!!\n";
while (my $line = <$IN> ){
print $OUT $line;
if ($line=~/^\s*\!\s*\$GEN\s+WrapperSubs/i) {
print $OUT "\n! Make n-D Array Buffers\n\n";
for my $type (@types) {
my $ftype = $ftypes{$type};
my $wordsz = $wordsizes{$type};
for my $mode ('Write') {
for my $dim (@dims) {
my $szstr=gen_szstr($dim);
$szstr=~s/\s*,\s*/*/g;
my $code_MakeArrayBuffer = "
subroutine oclMake${dim}D${type}Array${mode}Buffer(buffer, sz)
integer(8):: buffer
integer :: sz1d
integer, dimension($dim):: sz
integer(8) :: oclinstid
#ifdef OCL_MULTIPLE_DEVICES
call oclgetinstancec(oclinstmap, oclinstid)
#else
oclinstid = 0
#endif
sz1d = $szstr*$wordsz
call oclMake${mode}BufferC(ocl(oclinstid),buffer, sz1d)
end subroutine
";
print $OUT $code_MakeArrayBuffer;
}
} # mode
for my $mode (qw(Read ReadWrite)) {
for my $dim (@dims) {
my $szstr=gen_szstr($dim);
my $code_MakeArrayBuffer = "
subroutine oclMake${dim}D${type}Array${mode}Buffer(buffer, sz, array)
integer(8):: buffer
integer :: sz1d
integer, dimension($dim):: sz
$ftype,dimension($szstr) :: array
integer(8) :: oclinstid
#ifdef OCL_MULTIPLE_DEVICES
call oclgetinstancec(oclinstmap, oclinstid)
#else
oclinstid = 0
#endif
sz1d = size(array)*$wordsz
! print *, 'oclMake${dim}D${type}Array${mode}Buffer(',sz1d,')'
call oclMake${mode}BufferPtrC(ocl(oclinstid),buffer, sz1d, array)
end subroutine
";
print $OUT $code_MakeArrayBuffer;
} # dim
} # mode
} # types
print $OUT "\n! Write n-D Array Buffers\n\n";
for my $type (@types) {
my $ftype = $ftypes{$type};
my $wordsz = $wordsizes{$type};
for my $dim (@dims) {
my $szstr=gen_szstr($dim);
my $code_WriteBuffer = "
subroutine oclWrite${dim}D${type}ArrayBuffer(buffer, sz,array)
integer(8):: buffer
integer :: sz1d
integer, dimension($dim):: sz
$ftype, dimension($szstr) :: array
integer(8) :: oclinstid
#ifdef OCL_MULTIPLE_DEVICES
call oclgetinstancec(oclinstmap, oclinstid)
#else
oclinstid = 0
#endif
sz1d=size(array)*$wordsz
call oclwritebufferc(ocl(oclinstid),buffer, sz1d,array)
end subroutine
";
print $OUT $code_WriteBuffer;
} # dim
} # type
print $OUT "\n! Read n-D Array Buffers\n\n";
for my $type (@types) {
my $ftype = $ftypes{$type};
my $wordsz = $wordsizes{$type};
for my $dim (@dims) {
my $szstr=gen_szstr($dim);
my $code_ReadBuffer = "
subroutine oclRead${dim}D${type}ArrayBuffer(buffer,sz,array)
integer(8):: buffer
integer :: sz1d
integer, dimension($dim):: sz
$ftype,dimension($szstr) :: array
$ftype, dimension(size(array)):: array1d
integer(8) :: oclinstid
#ifdef OCL_MULTIPLE_DEVICES
call oclgetinstancec(oclinstmap, oclinstid)
#else
oclinstid = 0
#endif
sz1d = size(array)*$wordsz
call oclreadbufferc(ocl(oclinstid),buffer,sz1d,array1d)
array = reshape(array1d,shape(array))
end subroutine
";
print $OUT $code_ReadBuffer;
} # dim
} # type
} # line
} # loop over template source
close $IN;
close $OUT;