Skip to content

Commit f6df1fb

Browse files
committed
JavaCL: introduce CLPlatform.requireMinVersionValue to deal with OpenCL version requirements.
1 parent 98fb3f4 commit f6df1fb

8 files changed

Lines changed: 67 additions & 44 deletions

File tree

‎Core/src/main/velocity/com/nativelibs4java/opencl/CLBuffer.java‎

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -117,17 +117,13 @@ protected void checkBounds(long offset, long length) {
117117
* @return sub-buffer that is a "window" of this buffer starting at the provided offset, with the provided length
118118
*/
119119
public CLBuffer<T> createSubBuffer(Usage usage, long offset, long length) {
120-
try {
121-
int s = getElementSize();
122-
cl_buffer_region region = new cl_buffer_region().origin(s * offset).size(s * length);
123-
#declareReusablePtrsAndPErr()
124-
long mem = CL.clCreateSubBuffer(getEntity(), usage.getIntFlags(), CL_BUFFER_CREATE_TYPE_REGION, getPeer(getPointer(region)), getPeer(pErr));
125-
#checkPErr()
126-
return mem == 0 ? null : new CLBuffer<T>(context, length * s, mem, null, io);
127-
} catch (Throwable th) {
128-
// TODO check if supposed to handle OpenCL 1.1
129-
throw new UnsupportedOperationException("Cannot create sub-buffer (OpenCL 1.1 feature).", th);
130-
}
120+
context.getPlatform().requireMinVersionValue("clCreateSubBuffer", 1.1);
121+
int s = getElementSize();
122+
cl_buffer_region region = new cl_buffer_region().origin(s * offset).size(s * length);
123+
#declareReusablePtrsAndPErr()
124+
long mem = CL.clCreateSubBuffer(getEntity(), usage.getIntFlags(), CL_BUFFER_CREATE_TYPE_REGION, getPeer(getPointer(region)), getPeer(pErr));
125+
#checkPErr()
126+
return mem == 0 ? null : new CLBuffer<T>(context, length * s, mem, null, io);
131127
}
132128

133129
/**

‎Core/src/main/velocity/com/nativelibs4java/opencl/CLContext.java‎

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -168,15 +168,11 @@ else if ("false".equals(prop) || "0".equals(env))
168168
* @since OpenCL 1.1
169169
*/
170170
public CLUserEvent createUserEvent() {
171-
try {
172-
#declareReusablePtrsAndPErr()
173-
long evt = CL.clCreateUserEvent(getEntity(), getPeer(pErr));
174-
#checkPErr()
175-
return (CLUserEvent)CLEvent.createEvent(null, evt, true);
176-
} catch (Throwable th) {
177-
// TODO throw if supposed to handle OpenCL 1.1
178-
return null;
179-
}
171+
platform.requireMinVersionValue("clCreateUserEvent", 1.1);
172+
#declareReusablePtrsAndPErr()
173+
long evt = CL.clCreateUserEvent(getEntity(), getPeer(pErr));
174+
#checkPErr()
175+
return (CLUserEvent)CLEvent.createEvent(null, evt, true);
180176
}
181177

182178
/**

‎Core/src/main/velocity/com/nativelibs4java/opencl/CLDevice.java‎

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -653,12 +653,8 @@ public String getProfile() {
653653
*/
654654
@InfoName("CL_DEVICE_HOST_UNIFIED_MEMORY")
655655
public boolean isHostUnifiedMemory() {
656-
try {
657-
return infos.getBool(getEntity(), CL_DEVICE_HOST_UNIFIED_MEMORY);
658-
} catch (Throwable th) {
659-
// TODO throw if supposed to handle OpenCL 1.1
660-
return false;
661-
}
656+
platform.requireMinVersionValue("CL_DEVICE_HOST_UNIFIED_MEMORY", 1.1);
657+
return infos.getBool(getEntity(), CL_DEVICE_HOST_UNIFIED_MEMORY);
662658
}
663659
664660
/**

‎Core/src/main/velocity/com/nativelibs4java/opencl/CLEvent.java‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,8 @@ public void apply(@Ptr long evt, int executionStatus, @Ptr long callbackPeer) {
8989
* @since OpenCL 1.1
9090
*/
9191
public void setCallback(int commandExecStatus, final EventCallback callback) {
92-
try {
93-
error(CL.clSetEventCallback(getEntity(), commandExecStatus, eventCallbackPeer, JNI.newGlobalRef(callback)));
94-
} catch (UnsatisfiedLinkError th) {
95-
throw new UnsupportedOperationException("Cannot set event callback (OpenCL 1.1 feature): " + th, th);
96-
}
92+
queue.getContext().getPlatform().requireMinVersionValue("clSetEventCallback", 1.1);
93+
error(CL.clSetEventCallback(getEntity(), commandExecStatus, eventCallbackPeer, JNI.newGlobalRef(callback)));
9794
}
9895
9996
static CLEvent createEvent(final CLQueue queue, long evt) {

‎Core/src/main/velocity/com/nativelibs4java/opencl/CLException.java‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ public int getCode() {
3232
int value();
3333
}
3434

35+
public static class CLVersionException extends CLException {
36+
public CLVersionException(String message) {
37+
super(message, 0);
38+
}
39+
}
40+
3541
public static class CLTypedException extends CLException {
3642
protected String message;
3743
public CLTypedException() {
@@ -223,4 +229,4 @@ public static void error(int err) {
223229

224230
throw toThrow;
225231
}
226-
}
232+
}

‎Core/src/main/velocity/com/nativelibs4java/opencl/CLKernel.java‎

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,12 @@ public String toString() {
8282
* @since OpenCL 1.1
8383
*/
8484
public Map<CLDevice, Long> getPreferredWorkGroupSizeMultiple() {
85-
try {
86-
CLDevice[] devices = program.getDevices();
87-
Map<CLDevice, Long> ret = new HashMap<CLDevice, Long>(devices.length);
88-
for (CLDevice device : devices)
89-
ret.put(device, getKernelInfos().getIntOrLong(device.getEntity(), CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE));
90-
return ret;
91-
} catch (Throwable th) {
92-
// TODO check if supposed to handle OpenCL 1.1
93-
throw new UnsupportedOperationException("Cannot get CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE (OpenCL 1.1 feature).", th);
94-
}
85+
program.getContext().getPlatform().requireMinVersionValue("CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE", 1.1);
86+
CLDevice[] devices = program.getDevices();
87+
Map<CLDevice, Long> ret = new HashMap<CLDevice, Long>(devices.length);
88+
for (CLDevice device : devices)
89+
ret.put(device, getKernelInfos().getIntOrLong(device.getEntity(), CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE));
90+
return ret;
9591
}
9692

9793
/**
@@ -468,4 +464,4 @@ public String getFunctionName() {
468464
name = infos.getString(getEntity(), CL_KERNEL_FUNCTION_NAME);
469465
return name;
470466
}
471-
}
467+
}

‎Core/src/main/velocity/com/nativelibs4java/opencl/CLMem.java‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public interface DestructorCallback {
6464
* @param callback
6565
*/
6666
public void setDestructorCallback(final DestructorCallback callback) {
67+
context.getPlatform().requireMinVersionValue("clSetMemObjectDestructorCallback", 1.1);
6768
clSetMemObjectDestructorCallback_arg1_callback cb = new clSetMemObjectDestructorCallback_arg1_callback() {
6869
@Override
6970
public void apply(@Ptr long mem, @Ptr long userData) {

‎Core/src/main/velocity/com/nativelibs4java/opencl/CLPlatform.java‎

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313

1414
import java.nio.ByteOrder;
1515
import java.util.*;
16+
import java.util.regex.Matcher;
17+
import java.util.regex.Pattern;
18+
import java.util.logging.*;
19+
1620
import static com.nativelibs4java.opencl.JavaCL.*;
1721
import static com.nativelibs4java.opencl.CLException.*;
1822

@@ -397,6 +401,36 @@ public String getVersion() {
397401
return infos.getString(getEntity(), CL_PLATFORM_VERSION);
398402
}
399403

404+
private double versionValue = Double.NaN;
405+
private static final Pattern VERSION_PATTERN = Pattern.compile("OpenCL (\\d+\\.\\d+)\\b.*");
406+
double getVersionValue() {
407+
if (Double.isNaN(versionValue)) {
408+
String versionString = getVersion();
409+
Matcher matcher = VERSION_PATTERN.matcher(versionString);
410+
if (matcher.matches()) {
411+
String str = matcher.group(1);
412+
versionValue = Double.parseDouble(str);
413+
} else {
414+
log(Level.SEVERE, "Failed to parse OpenCL version: '" + versionString + "'");
415+
}
416+
}
417+
return versionValue;
418+
}
419+
void requireMinVersionValue(String feature, double minValue) {
420+
requireMinVersionValue(feature, minValue, Double.NaN);
421+
}
422+
void requireMinVersionValue(String feature, double minValue, double deprecationValue) {
423+
double value = getVersionValue();
424+
if (value < minValue) {
425+
throw new CLVersionException(feature + " requires OpenCL version " + minValue +
426+
" (detected version is " + value + ")");
427+
} else if (!(value < deprecationValue)) {
428+
// The above test will work fine (i.e. will fail) with NaN.
429+
log(Level.WARNING, feature + " is deprecated from OpenCL version " + deprecationValue +
430+
" (detected version is " + value + ")");
431+
}
432+
}
433+
400434
/**
401435
* Platform name string.
402436
*/
@@ -463,7 +497,8 @@ public boolean isGLSharingSupported() {
463497
*/
464498
@Deprecated
465499
public void unloadPlatformCompiler() {
466-
return clUnloadPlatformCompiler(getEntity());
500+
requireMinVersionValue("clUnloadPlatformCompiler", 1.1, 1.2);
501+
error(CL.clUnloadPlatformCompiler(getEntity()));
467502
}
468503

469504
}

0 commit comments

Comments
 (0)