ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/OpenCL/gengetinfo
Revision: 1.2
Committed: Sun Nov 20 10:25:17 2011 UTC (12 years, 6 months ago) by root
Branch: MAIN
Changes since 1.1: +2 -4 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #!/opt/bin/perl
2    
3     # almost every "if" or "?" in this file indicates a place where the OpenCL
4     # designers fucked it up - each time you have to remember an exception to
5     # the naming rules.
6    
7     use common::sense;
8    
9     my %classmap = qw(
10     platform Platform
11     device Device
12     context Context
13     event Event
14     profiling Event
15     mem Memory
16     image Image
17     sampler Sampler
18     program Program
19     program_build Program
20     kernel Kernel
21     kernel_work_group Kernel
22     command_queue Queue
23     );
24    
25     my %typemap = (
26     cl_bool => ['cl_bool', 'value [i] ? &PL_sv_yes : &PL_sv_no', 'boolean'],
27     #char => ['char', 'newSVpvn (value, size)', 'string'],
28     char => ['char', 'newSVpv (value, 0)', 'string'], # all these are 0-terminated strings, and the driver often appends a \0
29     size_t => ['size_t', 'newSVuv (value [i])', 'int'],
30     "void*" => ['void *', 'newSVuv ((IV)(intptr_t)value [i])', 'ptr_value'],
31     cl_platform_id => ['cl_platform_id', 'OpenCL::Platform'],
32     Context => ['cl_context', 'OpenCL::Context', 'ctx'],
33     Device => ['cl_device_id', 'OpenCL::Device', 'device'],
34     cl_device_id => ['cl_device_id', 'OpenCL::Device', 'device'],
35     Memory => ['cl_mem', 'OpenCL::Memory', 'mem'],
36     Program => ['cl_program', 'OpenCL::Program', 'program'],
37     CommandQueue => ['cl_command_queue', 'OpenCL::Queue', 'queue'],
38     cl_context_properties => ['cl_context_properties', 'newSVuv ((UV)value [i])', 'property_int'],
39     );
40    
41     {
42     my %tmap = (
43     T_IV => "newSViv (value [i])",
44     T_UV => "newSVuv (value [i])",
45     );
46    
47     open my $fh, "<typemap"
48     or die "typemap: $!";
49    
50     while (<$fh>) {
51     next if /^INPUT$/;
52     my ($name, $type) = split /\s+/, $_;
53     if ($tmap{$type}) {
54     $typemap{$name} = [$name, $tmap{$type}, substr $name, 3];
55     }
56     }
57     }
58    
59     sub patch($$$$) {
60     my ($file, $beg, $end, $contents) = @_;
61    
62     {
63     local $/;
64    
65     open my $fh, "<$file"
66     or die "$file: $!";
67    
68     my $data = <$fh>;
69     $data =~ s/^(\Q$beg\E\n).*?\n(\Q$end\E\n)/$1\n$contents$2/sm
70     or die "$file: couldn't find $beg/$end";
71    
72     open my $fh2, ">$file~"
73     or die "$file~: $!";
74    
75     syswrite $fh2, $data;
76     }
77    
78     rename "$file~", $file;
79     }
80    
81     for my $CLASS (qw(platform device context command_queue mem image sampler program program_build kernel kernel_work_group event profiling)) {
82     open my $fh, "<getinfo.txt"
83     or die "getinfo.txt: $!";
84    
85     my $XS;
86     my $POD;
87    
88     while (<$fh>) {
89     chomp;
90     my ($class, $name, $ctype) = split /,\s*/, $_, 3;
91     next unless $class eq "cl_$CLASS\_info";
92     next if $name eq "CL_IMAGE_FORMAT"; # struct
93     next if $name eq "CL_PROGRAM_BINARIES"; # needs multiple calls
94    
95     $ctype =~ s/cl:://g;
96     $ctype =~ s/::size_t/size_t/g;
97    
98     my $cbase = $class;
99     $cbase =~ s/_(.)/\U$1/g;
100     $cbase =~ s/^cl//;
101     $cbase =~ s/Info$//;
102     $cbase = "MemObject" if $cbase eq "Mem";
103     $cbase = "EventProfiling" if $cbase eq "Profiling";
104    
105     my $real_class = $CLASS;
106     $real_class = "program" if $real_class eq "program_build";
107     $real_class = "kernel" if $real_class eq "kernel_work_group";
108     $real_class = "event" if $real_class eq "profiling";
109    
110     my $perl_name = lc $name;
111     $perl_name =~ s/^cl_//;
112     $perl_name =~ s/^$real_class\_//;
113     $perl_name =~ s/^queue\_//;
114    
115     my $extra_args;
116     my $extra_perl_args;
117     my $extra_xs_args;
118    
119     if ($CLASS eq "program_build" || $CLASS eq "kernel_work_group") {
120     $extra_args = ', device';
121     $extra_perl_args = ' ($device)';
122     $extra_xs_args = ', OpenCL::Device device';
123     }
124    
125     my $dynamic;
126     my $nelem = "size / sizeof (value [0])";
127    
128     if ($ctype eq "STRING_CLASS") {
129     $ctype = "VECTOR_CLASS<char>";
130     $nelem = "1";
131     $dynamic = 1;
132     }
133    
134     my $type = $ctype;
135     my $array = 0;
136    
137     if ($type =~ s/^VECTOR_CLASS<\s*(.*)>$/$1/) {
138     $dynamic = 1;
139     $array = 1;
140     } elsif ($type =~ s/<(\d+)>$//) {
141     $dynamic = 1;
142     $array = 1;
143     }
144    
145     $type = $typemap{$type}
146     or die "$name: no mapping for $ctype";
147    
148     my $perltype = $type->[2];
149    
150     if ($array && $nelem ne "1") {
151     $perltype = "\@${perltype}s";
152     } else {
153     $perltype = "\$$perltype";
154     }
155    
156 root 1.2 $POD .= "=item $perltype = \$$real_class->$perl_name$extra_perl_args\n\nCalls C<clGet${cbase}Info> with C<$name> and returns the result(s).\n\n";
157 root 1.1
158     $XS .= "void\n"
159     . "$perl_name (OpenCL::$classmap{$real_class} this$extra_xs_args)\n"
160     . " PPCODE:\n";
161    
162     if ($dynamic) {
163     $XS .= " size_t size;\n"
164     . " NEED_SUCCESS (Get${cbase}Info, (this$extra_args, $name, 0, 0, &size));\n"
165     . " $type->[0] *value = tmpbuf (size);\n"
166     . " NEED_SUCCESS (Get${cbase}Info, (this$extra_args, $name, size, value, 0));\n";
167     } else {
168     $XS .= " $type->[0] value [1];\n"
169     . " NEED_SUCCESS (Get${cbase}Info, (this$extra_args, $name, sizeof (value), value, 0));\n";
170     }
171    
172     if ($array) {
173     $XS .= " int i, n = $nelem;\n"
174     . " EXTEND (SP, n);\n"
175     . " for (i = 0; i < n; ++i)\n";
176     } else {
177     $XS .= " EXTEND (SP, 1);\n"
178     . " const int i = 0;\n"
179     }
180    
181     if ($type->[1] =~ /^OpenCL::(\S+)$/) {
182     my $oclass = $1;
183     $oclass = "MemObject" if $oclass eq "Memory";
184     $oclass = "CommandQueue" if $oclass eq "Queue";
185    
186     $XS .= " {\n";
187     $XS .= " NEED_SUCCESS (Retain$oclass, (value [i]));\n" unless $1 eq "Platform" || $1 eq "Device";
188     $XS .= " PUSHs (NEW_MORTAL_OBJ (\"$type->[1]\", value [i]));\n";
189     $XS .= " }\n";
190     } else {
191     $XS .= " PUSHs (sv_2mortal ($type->[1]));\n";
192     }
193    
194     $XS .= "\n";
195     }
196    
197     patch "OpenCL.xs", "#BEGIN:$CLASS" , "#END:$CLASS" , $XS;
198 root 1.2 patch "OpenCL.pm", "=for gengetinfo begin $CLASS", "=for gengetinfo end $CLASS", $POD;
199 root 1.1 }
200