/** Returns the context of this program */ public synchronized CLProgram build() throws CLBuildException { if (built) throw new IllegalThreadStateException("Program was already built !"); String contentSignature = null; File cacheFile = null; boolean readBinaries = false; if (isCached()) { try { contentSignature = computeCacheSignature(); byte[] sha = java.security.MessageDigest.getInstance("MD5") .digest(contentSignature.getBytes(textEncoding)); StringBuilder shab = new StringBuilder(); for (byte b : sha) shab.append(Integer.toHexString(b & 0xff)); String hash = shab.toString(); cacheFile = new File(JavaCL.userCacheDir, hash); if (cacheFile.exists()) { Pair<Map<CLDevice, byte[]>, String> bins = readBinaries( Arrays.asList(getDevices()), contentSignature, new FileInputStream(cacheFile)); setBinaries(bins.getFirst()); this.source = bins.getSecond(); assert log(Level.INFO, "Read binaries cache from '" + cacheFile + "'"); readBinaries = true; } } catch (Exception ex) { assert log(Level.WARNING, "Failed to load cached program", ex); entity = null; } } if (entity == null) allocate(); Runnable deleteTempFiles = null; if (!readBinaries) try { deleteTempFiles = copyIncludesToTemporaryDirectory(); } catch (IOException ex) { throw new CLBuildException(this, ex.toString(), Collections.EMPTY_LIST); } int nDevices = devices.length; cl_device_id[] deviceIds = null; if (nDevices != 0) { deviceIds = new cl_device_id[nDevices]; for (int i = 0; i < nDevices; i++) deviceIds[i] = devices[i].getEntity(); } int err = CL.clBuildProgram( getEntity(), nDevices, deviceIds, readBinaries ? null : getOptionsString(), null, null); // int err = CL.clBuildProgram(getEntity(), 0, null, getOptionsString(), null, null); if (err != CL_SUCCESS) { // BUILD_PROGRAM_FAILURE) { NativeSizeByReference len = new NativeSizeByReference(); int bufLen = 2048 * 32; // TODO find proper size Memory buffer = new Memory(bufLen); HashSet<String> errs = new HashSet<String>(); if (deviceIds == null) { error( CL.clGetProgramBuildInfo( getEntity(), null, CL_PROGRAM_BUILD_LOG, toNS(bufLen), buffer, len)); String s = buffer.getString(0); errs.add(s); } else for (cl_device_id device : deviceIds) { error( CL.clGetProgramBuildInfo( getEntity(), device, CL_PROGRAM_BUILD_LOG, toNS(bufLen), buffer, len)); String s = buffer.getString(0); errs.add(s); } throw new CLBuildException(this, "Compilation failure : " + errorString(err), errs); } built = true; if (deleteTempFiles != null) deleteTempFiles.run(); if (isCached() && !readBinaries) { JavaCL.userCacheDir.mkdirs(); try { Map<CLDevice, byte[]> binaries = getBinaries(); if (!binaries.isEmpty()) { writeBinaries( getBinaries(), getSource(), contentSignature, new FileOutputStream(cacheFile)); assert log(Level.INFO, "Wrote binaries cache to '" + cacheFile + "'"); } } catch (Exception ex) { new IOException("[JavaCL] Failed to cache program", ex).printStackTrace(); } } return this; }
@Override protected synchronized cl_program getEntity() { if (entity == null) allocate(); return entity; }