From 6f003abc0703de86ed9add68bfe905c886801636 Mon Sep 17 00:00:00 2001 From: Not Zed Date: Tue, 1 Feb 2022 06:37:06 +1030 Subject: [PATCH] Small fixes --- src/generate-native | 63 ++++++++++++++++++++++++++++-------- src/template/Memory.java | 47 +++++++++++++++++++++++---- test-opencl-basic/opencl.api | 26 ++++++++++++--- 3 files changed, 111 insertions(+), 25 deletions(-) diff --git a/src/generate-native b/src/generate-native index d8d2497..b17434c 100755 --- a/src/generate-native +++ b/src/generate-native @@ -184,6 +184,12 @@ sub findRoots { foreach $func (@list) { $seen{"func:$func->{name}"} ++; } + } elsif ($inc->{mode} eq 'call') { + my @list = grep { $_->{type} eq $inc->{mode} && $_->{name} =~ m/$inc->{regex}/ } values %data; + + foreach $func (@list) { + $seen{"call:$func->{name}"} ++; + } } } } @@ -313,7 +319,7 @@ sub analyseAPI { } elsif ($o =~ m/^access=([rwi]+)$/) { $obj->{access} = $1; } elsif ($o =~ m/^success=(.*)$/) { - # for functions + # for functions? $obj->{success} = $1; } elsif ($o =~ m@^(rename|field:rename|func:rename)=(.*)@) { my $target = $1; @@ -336,10 +342,10 @@ sub analyseAPI { my $defmode = $obj->{type} eq 'library' ? 'func' : 'field'; foreach $inc (@{$obj->{items}}) { - if ($inc->{match} =~ m@^(field|func|define|struct|enum):/(.*)/$@) { + if ($inc->{match} =~ m@^(field|func|define|struct|enum|call):/(.*)/$@) { $inc->{regex} = qr/$2/; $inc->{mode} = $1; # ?? "$1-include"; - } elsif ($inc->{match} =~ m@^(field|func|define|struct|enum):(.*)$@) { + } elsif ($inc->{match} =~ m@^(field|func|define|struct|enum|call):(.*)$@) { $inc->{regex} = qr/^$2$/; $inc->{mode} = $1; } elsif ($inc->{match} =~ m@^/(.*)/$@) { @@ -547,7 +553,7 @@ sub formatTypeLayout { } sub formatFunctionDescriptor { - my $c = shift @_; + my $c = shift; my @arguments = @{$c->{arguments}}; my $result = $c->{result}; my $desc; @@ -862,6 +868,7 @@ sub formatFunction { my $r = $c->{result_code}; $desc .= "$r->{typeInfo}->{type} $r->{name}\$value;\n"; } + $desc .= "$result->{typeInfo}->{carrier} res\$value;\n" if ($rtype ne "void"); $desc .= " try "; $desc .= "(Frame frame = Memory.createFrame()) " if ($c->{resolveFrame}); @@ -872,7 +879,7 @@ sub formatFunction { $desc .= " $r->{typeInfo}->{declare};\n"; } - $desc .= " $result->{typeInfo}->{carrier} res\$value = ($result->{typeInfo}->{carrier})" if ($rtype ne "void"); + $desc .= " res\$value = ($result->{typeInfo}->{carrier})" if ($rtype ne "void"); $desc .= " " if ($rtype eq "void"); $index = 0; @@ -896,6 +903,8 @@ sub formatFunction { } $desc .= ");\n"; + my $error_value; + if ($rtype ne "void") { my $create = $result->{typeInfo}->{create}; @@ -908,16 +917,27 @@ sub formatFunction { $create =~ s/\$\{scope\}/scope()/; } + my $success; + if ($c->{result_code}) { my $r = $c->{result_code}; - my $success = $c->{success} ? $c->{success} : '0'; - $desc .= " $r->{name}\$value = $r->{name}.get(0);\n"; + $error_value = "$r->{name}\$value"; + $desc .= " $error_value = $r->{name}.get(0);\n"; + $success = $c->{success} ? $c->{success} : '0'; + } elsif ($c->{success}) { + $success = $c->{success}; + $error_value = "res\$value"; + } elsif ($inc->{success}) { + $success = $inc->{success}; + $error_value = "res\$value"; + } + if ($success) { $desc .= " if ("; $count = 0; foreach $s (split /,/,$success) { $desc .= " || " if ($count++ > 0); - $desc .= "($r->{name}\$value == $s)"; + $desc .= "($error_value == $s)"; } $desc .= ")\n"; } @@ -928,9 +948,8 @@ sub formatFunction { $desc .= " } catch (Throwable t) { throw new RuntimeException(t); }\n"; # assume it's an int - if ($c->{result_code}) { - my $r = $c->{result_code}; - $desc .= " throw new RuntimeException(String.format(\"error=%d\", $r->{name}\$value));\n"; + if ($error_value) { + $desc .= " throw new RuntimeException(String.format(\"error=%d\", $error_value));\n"; } $desc .="}"; @@ -1278,7 +1297,7 @@ sub exportStruct { # TODO: parameterise and use typeInfo data. if (!$isHandle) { - print $f " MemorySegment segment;\n"; + print $f " public final MemorySegment segment;\n"; # constructors print $f " private $s->{name}(MemorySegment segment) { this.segment = segment; }\n"; print $f " public static $s->{name} create(MemorySegment segment) { return new $s->{name}(segment); }\n"; @@ -1514,9 +1533,27 @@ foreach $obj ( @{$api->{struct}} ) { } } +# find flag +sub flag { + my $obj = shift; + my $flag = shift; + + return grep { $_ eq $flag } @{$obj->{options}}; +} + +# find option(s) +sub option { + my $obj = shift; + my $name = shift; + my $rx = qr/^$name=/; + + return grep { $_ =~ m/$rx/ } @{$obj->{options}}; +} + # Dump library type foreach $lib ( @{$api->{library}} ) { my $path = nameToPath($output, "$package.$lib->{name}"); + my $dynamic = flag($lib, 'dynamic'); open (my $f, ">", $path) || die ("Cannot open '$path' for writing"); @@ -1525,10 +1562,8 @@ foreach $lib ( @{$api->{library}} ) { print $f "import java.lang.invoke.*;\n"; print $f "public class $lib->{name} {\n"; - print $f " static ResourceScope scope() { return ResourceScope.globalScope(); }\n"; - # scan for matches foreach $inc (@{$lib->{items}}) { if ($inc->{mode} eq 'func') { my @list = grep { $_->{type} eq $inc->{mode} && $_->{name} =~ m/$inc->{regex}/ } values %data; diff --git a/src/template/Memory.java b/src/template/Memory.java index 89b4c6c..b720f99 100644 --- a/src/template/Memory.java +++ b/src/template/Memory.java @@ -157,6 +157,11 @@ public class Memory { ResourceScope scope(); } + public interface Array { + long length(); + T getAtIndex(long i); + } + public record FunctionPointer(NativeSymbol symbol, T function) { } @@ -172,10 +177,18 @@ public class Memory { return v != null ? v.symbol().address() : MemoryAddress.NULL; } - public static long size(List list) { + public static long length(List list) { return list != null ? list.size() : 0; } + public static long length(Array list) { + return list != null ? list.length() : 0; + } + + public static long size(MemorySegment s) { + return s != null ? s.byteSize() : 0; + } + // hmm do i want this or not? // -> added 'type safety' // -> load of crap to be written @@ -194,6 +207,10 @@ public class Memory { return create(MemorySegment.ofAddress(address, length, scope)); } + public static ByteArray createArray(MemoryAddress address, ResourceScope scope) { + return create(MemorySegment.ofAddress(address, Long.MAX_VALUE, scope)); + } + public static ByteArray createArray(long length, SegmentAllocator alloc) { return create(alloc.allocateArray(Memory.BYTE, length)); } @@ -256,7 +273,11 @@ public class Memory { } public static ShortArray createArray(MemoryAddress address, long length, ResourceScope scope) { - return create(MemorySegment.ofAddress(address, length, scope)); + return create(MemorySegment.ofAddress(address, length * Memory.SHORT.byteSize(), scope)); + } + + public static ShortArray createArray(MemoryAddress address, ResourceScope scope) { + return create(MemorySegment.ofAddress(address, Long.MAX_VALUE, scope)); } public static ShortArray createArray(long length, SegmentAllocator alloc) { @@ -317,7 +338,11 @@ public class Memory { } public static IntArray createArray(MemoryAddress address, long length, ResourceScope scope) { - return create(MemorySegment.ofAddress(address, length, scope)); + return create(MemorySegment.ofAddress(address, length * Memory.INT.byteSize(), scope)); + } + + public static IntArray createArray(MemoryAddress address, ResourceScope scope) { + return create(MemorySegment.ofAddress(address, Long.MAX_VALUE, scope)); } public static IntArray createArray(long length, SegmentAllocator alloc) { @@ -378,7 +403,7 @@ public class Memory { } public static LongArray createArray(MemoryAddress address, long length, ResourceScope scope) { - return create(MemorySegment.ofAddress(address, length, scope)); + return create(MemorySegment.ofAddress(address, length * Memory.LONG.byteSize(), scope)); } public static LongArray createArray(long length, SegmentAllocator alloc) { @@ -439,7 +464,11 @@ public class Memory { } public static FloatArray createArray(MemoryAddress address, long length, ResourceScope scope) { - return create(MemorySegment.ofAddress(address, length, scope)); + return create(MemorySegment.ofAddress(address, length * FLOAT.byteSize(), scope)); + } + + public static FloatArray createArray(MemoryAddress address, ResourceScope scope) { + return create(MemorySegment.ofAddress(address, Long.MAX_VALUE, scope)); } public static FloatArray createArray(long length, SegmentAllocator alloc) { @@ -500,7 +529,11 @@ public class Memory { } public static DoubleArray createArray(MemoryAddress address, long length, ResourceScope scope) { - return create(MemorySegment.ofAddress(address, length, scope)); + return create(MemorySegment.ofAddress(address, length * Memory.DOUBLE.byteSize(), scope)); + } + + public static DoubleArray createArray(MemoryAddress address, ResourceScope scope) { + return create(MemorySegment.ofAddress(address, Long.MAX_VALUE, scope)); } public static DoubleArray createArray(long length, SegmentAllocator alloc) { @@ -612,7 +645,7 @@ public class Memory { // This needs a separate scope from the array itself public static class HandleArray extends AbstractList implements Memory.Addressable { - final MemorySegment segment; + public final MemorySegment segment; final ResourceScope scope; BiFunction create; diff --git a/test-opencl-basic/opencl.api b/test-opencl-basic/opencl.api index 3728ba6..eeb8308 100644 --- a/test-opencl-basic/opencl.api +++ b/test-opencl-basic/opencl.api @@ -5,9 +5,17 @@ struct cl_image_format access=rwi { struct /^_cl/ access= rename=s/^_cl/cl/ { } + +# idea: dynamic will have a constructor that takes a SymbolLookup +# and ResourceScope +#library CLExt dynamic { +# clIcdGetPlatformIDsKHR +#} + library CL { define:CLConstants + # core functions, resolved by dlopen clGetPlatformIDs clGetPlatformInfo clGetDeviceIDs @@ -116,24 +124,34 @@ library CL { clCreateCommandQueue clCreateSampler clEnqueueTask - } + # base constants define CLConstants opencl.h { /.*/cl.h/ file-include } +define CLPlatformConstants opencl.h { + /^CL_API_/ exclude + CL_PROGRAM_STRING_DEBUG_INFO exclude + /^__CL_/ exclude + # huge/nan/infinity in c aren't compatible with java's string representation + CL_HUGE_VALF|CL_HUGE_VAL|CL_NAN|CL_INFINITY exclude + /.*/cl_platform.h/ file-include + +} + func clGetPlatformIDs { - num_entries implied=Memory.size(platforms) + num_entries implied=Memory.length(platforms) } func clGetDeviceIDs { - num_entries implied=Memory.size(devices) + num_entries implied=Memory.length(devices) } func clCreateContext { - num_devices implied=Memory.size(devices) + num_devices implied=Memory.length(devices) errcode_ret result_code success=CL_SUCCESS } -- 2.39.5