diff --git a/jminer.default.properties b/jminer.default.properties index aac911b..2bd2fd2 100644 --- a/jminer.default.properties +++ b/jminer.default.properties @@ -6,11 +6,12 @@ # # Requirements: # - Java8 (64bit recommend to use more memory) -# - openCL 1.2 or 2.0 (use jminer 0.3.6 for openCL 1.1) +# - openCL # # PLEASE DONATE # -# jminer would not be possible without openCL kernels and java code provided by 'burstDev', he really deserves some tips for that! +# jminer would not be possible without openCL kernels and java code provided by 'burstDev', +# he really deserves some tips for that! # BURST-QHCJ-9HB5-PTGC-5Q8J9 # # Feel free to support future development of mining engine ... @@ -102,10 +103,6 @@ optDevPool=false # ----------------------------------------------------------------------------------- # - MINING MODE - SOLO ---------------------------------- ONLY NEEDED 4 SOLO MINING - # ----------------------------------------------------------------------------------- -# -# Solo means you send your PASS on commit results! -# DO NOT try to use a online wallet or pool as Server! -# # soloServer - WARN! soloServer should be http://localhost:8125 or http://127.0.0.1:8125 # (default: Solo means you send your PASS on commit results! # http://localhost:8125) DO NOT try to use a online wallet or pool as Server! @@ -121,11 +118,9 @@ passPhrase=xxxxxxxxxxxxxx targetDeadline= # ----------------------------------------------------------------------------------- -# - GPU ----------------------------------------------------------------------------- +# - OpenCL ----------------------------------------------------------------------------- # ----------------------------------------------------------------------------------- -# the miner was tested on AMD and NVIDIA GPUs, feedback about CPU and unsupported GPUs is welcome -# -# the miner uses openCL for most of the mining calculations, ensure it is setup correctly. +# The miner uses openCL for most of the mining calculations, ensure it is setup correctly. # Instructions can be found e.g. here (thanks cryo): # https://github.com/bhamon/gpuPlotGenerator/blob/master/README.md # You could also use that instruction to find your platformId and deviceId if needed. @@ -149,12 +144,25 @@ deviceId= # (default:12000) this timeout is used for all network requests. # if you use pool or online-wallet, the 12 sec. default may # cause timeout on committing nonces or getting mining info etc. +# +# debug - setting 'debug' to true will log additional information of the mining process, +# (default:false) that are not related to mining, but to miner internals. +# +# writeLogFile - setting 'writeLogFile' to 'true' will write all logs from console to a file, too. +# (default:false) the name of that file can be specified by 'logFilePath'. +# +# logFilePath - path (filename and optional directory, relative to miner location) +# (default:log/jminer.log.txt) # ----------------------------------------------------------------------------------- refreshInterval=2000 connectionTimeout=12000 +debug= +writeLogFile= +logFilePath= + # ----------------------------------------------------------------------------------- -# - MINING ENGINE - APPEARANCE ------------------------------------------------------ +# - MINING ENGINE - APPEARANCE / BEHAVIOR ------------------------------------------- # ----------------------------------------------------------------------------------- # readProgressPerRound - defines how often the mining progress is shown per round # (default:9) thats the 'xx% done ...' info. diff --git a/pom.xml b/pom.xml index 3baeea6..3b50e2a 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ burstcoin burstcoin-jminer - 0.4.3-SNAPSHOT + 0.4.4-SNAPSHOT jar burstcoin-jminer @@ -20,10 +20,10 @@ UTF-8 - burstcoin.jminer.CommandLineRunner + burstcoin.jminer.JMinerApplication 1.8 9.3.8.RC0 - 0.2.0-RC00 + 0.1.9 3.0.1 1.46 diff --git a/src/main/java/burstcoin/jminer/JMinerApplication.java b/src/main/java/burstcoin/jminer/JMinerApplication.java new file mode 100644 index 0000000..8297bb0 --- /dev/null +++ b/src/main/java/burstcoin/jminer/JMinerApplication.java @@ -0,0 +1,68 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016 by luxe - https://github.com/de-luxe - BURST-LUXE-RED2-G6JW-H4HG5 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software + * is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies + * or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package burstcoin.jminer; + +import burstcoin.jminer.core.CoreProperties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.Banner; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; + +import java.util.HashMap; +import java.util.Map; + +@SpringBootApplication +public class JMinerApplication +{ + private static final Logger LOG = LoggerFactory.getLogger(JMinerApplication.class); + + public static void main(String[] args) + { + LOG.info("Starting the engines ... please wait!"); + + // overwritten by application.properties + Map properties = new HashMap<>(); + if(CoreProperties.isWriteLogFile()) + { + properties.put("logging.file", CoreProperties.getLogFilePath()); + } + properties.put("logging.level.burstcoin.jminer.core", CoreProperties.isDebug() ? "DEBUG" : "INFO"); + + new SpringApplicationBuilder(JMinerApplication.class) + .bannerMode(Banner.Mode.OFF) // turn off spring boot banner + .logStartupInfo(false) + .properties(properties) // add application.properties + .build(args) + .run(); + } + + @Bean + public CommandLineRunner getCommandLineRunner(ConfigurableApplicationContext context) + { + return new JMinerCommandLine(context); + } +} diff --git a/src/main/java/burstcoin/jminer/CommandLineRunner.java b/src/main/java/burstcoin/jminer/JMinerCommandLine.java similarity index 95% rename from src/main/java/burstcoin/jminer/CommandLineRunner.java rename to src/main/java/burstcoin/jminer/JMinerCommandLine.java index 073fcd8..dfd1f1a 100644 --- a/src/main/java/burstcoin/jminer/CommandLineRunner.java +++ b/src/main/java/burstcoin/jminer/JMinerCommandLine.java @@ -42,18 +42,18 @@ import burstcoin.jminer.core.round.event.RoundStoppedEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.CommandLineRunner; import org.springframework.context.ApplicationListener; import org.springframework.context.ConfigurableApplicationContext; import java.math.BigDecimal; import java.math.MathContext; -@SpringBootApplication -public class CommandLineRunner + +public class JMinerCommandLine + implements CommandLineRunner { - private static final Logger LOG = LoggerFactory.getLogger(CommandLineRunner.class); + private static final Logger LOG = LoggerFactory.getLogger(JMinerCommandLine.class); private static final int NUMBER_OF_PROGRESS_LOGS_PER_ROUND = CoreProperties.getReadProgressPerRound(); @@ -67,11 +67,37 @@ public class CommandLineRunner private static long previousRemainingCapacity = 0; private static long previousElapsedTime = 0; - public static void main(String[] args) + private ConfigurableApplicationContext context; + + public JMinerCommandLine(ConfigurableApplicationContext context) + { + this.context = context; + } + + @Override + public void run(String... args) + throws Exception { - LOG.info("start the engines ..."); - ConfigurableApplicationContext context = SpringApplication.run(CommandLineRunner.class); + initApplicationListeners(); + LOG.info("-------------------------------------------------------"); + LOG.info(" Burstcoin (BURST)"); + LOG.info(" __ __ GPU assisted PoC-Miner"); + LOG.info(" |__| _____ |__| ____ ___________ "); + LOG.info(" version | |/ \\| |/ \\_/ __ \\_ __ \\"); + LOG.info(" 0.4.4 | | Y Y \\ | | \\ ___/| | \\/"); + LOG.info(" /\\__| |__|_| /__|___| /\\___ >__| "); + LOG.info(" \\______| \\/ \\/ \\/"); + LOG.info(" mining engine: BURST-LUXE-RED2-G6JW-H4HG5"); + LOG.info(" openCL checker: BURST-QHCJ-9HB5-PTGC-5Q8J9"); + + Network network = context.getBean(Network.class); + network.checkPoolInfo(); + network.startMining(); + } + + private void initApplicationListeners() + { context.addApplicationListener(new ApplicationListener() { @Override @@ -312,24 +338,9 @@ public void onApplicationEvent(NetworkPoolInfoEvent event) LOG.info(" balance '" + amount + " BURST', total mined '" + totalForget + " BURST'"); } }); - - LOG.info(""); - LOG.info(" Burstcoin (BURST)"); - LOG.info(" __ __ GPU assisted PoC-Miner"); - LOG.info(" |__| _____ |__| ____ ___________ "); - LOG.info(" version | |/ \\| |/ \\_/ __ \\_ __ \\"); - LOG.info(" 0.4.3 | | Y Y \\ | | \\ ___/| | \\/"); - LOG.info(" /\\__| |__|_| /__|___| /\\___ >__| "); - LOG.info(" \\______| \\/ \\/ \\/"); - LOG.info(" mining engine: BURST-LUXE-RED2-G6JW-H4HG5"); - LOG.info(" openCL checker: BURST-QHCJ-9HB5-PTGC-5Q8J9"); - - Network network = context.getBean(Network.class); - network.checkPoolInfo(); - network.startMining(); } - private static String getDeadlineTime(Long calculatedDeadline) + private String getDeadlineTime(Long calculatedDeadline) { long sec = calculatedDeadline; long min = sec / 60; diff --git a/src/main/java/burstcoin/jminer/core/CoreProperties.java b/src/main/java/burstcoin/jminer/core/CoreProperties.java index d0f27bc..a39715e 100644 --- a/src/main/java/burstcoin/jminer/core/CoreProperties.java +++ b/src/main/java/burstcoin/jminer/core/CoreProperties.java @@ -62,6 +62,10 @@ public class CoreProperties private static final boolean DEFAULT_LIST_PLOT_FILES = false; private static final boolean DEFAULT_SHOW_DRIVE_INFO = false; private static final int DEFAULT_READER_THREADS = 0; + private static final boolean DEFAULT_DEBUG = false; + private static final boolean DEFAULT_WRITE_LOG_FILE = false; + private static final String DEFAULT_LOG_FILE_PATH = "log/jminer.log.txt"; + // there seams to be a issue on checker private static final boolean DEFAULT_OPT_DEV_POOL = false; @@ -102,6 +106,9 @@ public class CoreProperties private static Boolean listPlotFiles; private static Boolean showDriveInfo; private static Integer readerThreads; + private static Boolean writeLogFile; + private static Boolean debug; + private static String logFilePath; private CoreProperties() { @@ -453,6 +460,33 @@ public static boolean isShowDriveInfo() return showDriveInfo; } + public static boolean isWriteLogFile() + { + if(writeLogFile == null) + { + writeLogFile = asBoolean("writeLogFile", DEFAULT_WRITE_LOG_FILE); + } + return writeLogFile; + } + + public static boolean isDebug() + { + if(debug == null) + { + debug = asBoolean("debug", DEFAULT_DEBUG); + } + return debug; + } + + public static String getLogFilePath() + { + if(logFilePath == null) + { + logFilePath = asString("logFilePath", DEFAULT_LOG_FILE_PATH); + } + return logFilePath; + } + private static Boolean asBoolean(String key, boolean defaultValue) { String booleanProperty = PROPS.containsKey(key) ? String.valueOf(PROPS.getProperty(key)) : null; diff --git a/src/main/java/burstcoin/jminer/core/checker/util/OCLChecker.java b/src/main/java/burstcoin/jminer/core/checker/util/OCLChecker.java index 7f0d4f7..d484dba 100644 --- a/src/main/java/burstcoin/jminer/core/checker/util/OCLChecker.java +++ b/src/main/java/burstcoin/jminer/core/checker/util/OCLChecker.java @@ -33,7 +33,10 @@ import org.jocl.cl_mem; import org.jocl.cl_platform_id; import org.jocl.cl_program; -import org.jocl.cl_queue_properties; +import org.jocl.utils.DeviceInfos; +import org.jocl.utils.Devices; +import org.jocl.utils.PlatformInfos; +import org.jocl.utils.Platforms; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Scope; @@ -44,6 +47,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.List; import static org.jocl.CL.*; @@ -56,6 +60,11 @@ public class OCLChecker { private static final Logger LOG = LoggerFactory.getLogger(OCLChecker.class); + private static final int SIZE_DIVISOR = CoreProperties.isByteUnitDecimal() ? 1000 : 1024; + private static final String T_UNIT = CoreProperties.isByteUnitDecimal() ? "TB" : "TiB"; + private static final String G_UNIT = CoreProperties.isByteUnitDecimal() ? "GB" : "GiB"; + private static final String M_UNIT = CoreProperties.isByteUnitDecimal() ? "MB" : "MiB"; + cl_context context; cl_command_queue queue; cl_program program; @@ -75,6 +84,8 @@ protected void postConstruct() public void initChecker(int platformId, int deviceId) { + check(); + setExceptionsEnabled(true); int numPlatforms[] = new int[1]; @@ -89,7 +100,7 @@ public void initChecker(int platformId, int deviceId) clGetPlatformIDs(platforms.length, platforms, null); int[] numDevices = new int[1]; - clGetDeviceIDs(platforms[platformId], CL_DEVICE_TYPE_GPU, 0, null, numDevices); + clGetDeviceIDs(platforms[platformId], CL_DEVICE_TYPE_ALL, 0, null, numDevices); if(deviceId >= numDevices[0]) { @@ -97,25 +108,13 @@ public void initChecker(int platformId, int deviceId) } cl_device_id devices[] = new cl_device_id[numDevices[0]]; - clGetDeviceIDs(platforms[platformId], CL_DEVICE_TYPE_GPU, devices.length, devices, null); + clGetDeviceIDs(platforms[platformId], CL_DEVICE_TYPE_ALL, devices.length, devices, null); cl_context_properties contextProperties = new cl_context_properties(); contextProperties.addProperty(CL_CONTEXT_PLATFORM, platforms[platformId]); context = clCreateContext(contextProperties, 1, new cl_device_id[]{devices[deviceId]}, null, null, null); - - boolean openCl2 = true; - try - { - // openCL 2.0 - queue = clCreateCommandQueueWithProperties(context, devices[deviceId], new cl_queue_properties(), null); - } - catch(UnsupportedOperationException e) - { - // org. - fallback for openCL 1.2 - openCl2 = false; - queue = clCreateCommandQueue(context, devices[deviceId], 0, null); - } + queue = clCreateCommandQueue(context, devices[deviceId], 0, null); String kernelSource; try @@ -142,18 +141,53 @@ public void initChecker(int platformId, int deviceId) clGetKernelWorkGroupInfo(kernel[i], devices[deviceId], CL_KERNEL_WORK_GROUP_SIZE, 8, Pointer.to(maxWorkGroupSize), null); workgroupSize[i] = maxWorkGroupSize[0]; } - LOG.debug("Max work group size: " + maxWorkGroupSize[0]); long[] maxComputeUnits = new long[1]; clGetDeviceInfo(devices[deviceId], CL_DEVICE_MAX_COMPUTE_UNITS, 8, Pointer.to(maxComputeUnits), null); - LOG.debug("Max compute units: " + maxComputeUnits[0]); computeUnits = maxComputeUnits[0]; - gensigMem = clCreateBuffer(context, CL_MEM_READ_ONLY, 32, null, null); bestMem = clCreateBuffer(context, CL_MEM_WRITE_ONLY, 400, null, null); // org 400 // tested 5000 - LOG.info("success ... started openCL " + (openCl2 ? "2.0" : "1.2") + " context!"); + LOG.info(""); + LOG.info("(*) openCL context successfully started! (platformId: "+platformId+", deviceId: "+deviceId+")"); + LOG.info("-------------------------------------------------------"); + } + + private void check() + { + List platforms = Platforms.getPlatforms(); + LOG.info("-------------------------------------------------------"); + LOG.info("List of system openCL platforms and devices (* = used for mining)"); + LOG.info(""); + for(cl_platform_id cl_platform_id : platforms) + { + int currentPlatformId = platforms.indexOf(cl_platform_id); + if(currentPlatformId == CoreProperties.getPlatformId()) + { + + String selector = " * "; + String selectionPrefix = currentPlatformId == CoreProperties.getPlatformId() ? selector : " "; + LOG.info(selectionPrefix + "PLATFORM-[" + currentPlatformId + "] " + PlatformInfos.getName(cl_platform_id) + " - " + + "(" + PlatformInfos.getVersion(cl_platform_id) + ")"); + + List devices = Devices.getDevices(cl_platform_id); + for(cl_device_id cl_device_id : devices) + { + int currentDeviceId = devices.indexOf(cl_device_id); + selectionPrefix = currentDeviceId == CoreProperties.getDeviceId() ? selector : " "; + + LOG.info(selectionPrefix + " DEVICE-[" + currentDeviceId + "] " + DeviceInfos.getName(cl_device_id) + " " + + "(" + bytesAsGigabyte(DeviceInfos.getMaxMemAllocSize(cl_device_id)) + ")" + + " - " + DeviceInfos.getVendor(cl_device_id) + " (" + DeviceInfos.getDeviceVersion(cl_device_id) + + " | '" + DeviceInfos.getDriverVersion(cl_device_id) + "')"); + LOG.info(selectionPrefix + " [" + currentDeviceId + "] " + + "work group size: '" + DeviceInfos.getMaxWorkGroupSize(cl_device_id) + "', " + + "computing units: '" + DeviceInfos.getMaxComputeUnits(cl_device_id) + "', " + + "available '" + DeviceInfos.getAvailable(cl_device_id) + "'"); + } + } + } } public void reset(int platformId, int deviceId) @@ -162,6 +196,11 @@ public void reset(int platformId, int deviceId) initChecker(platformId, deviceId); } + private String bytesAsGigabyte(long bytes) + { + return bytes / SIZE_DIVISOR / SIZE_DIVISOR / SIZE_DIVISOR % SIZE_DIVISOR + "" + G_UNIT; + } + public int findLowest(byte[] gensig, byte[] data) { cl_mem dataMem; diff --git a/src/main/java/burstcoin/jminer/core/network/Network.java b/src/main/java/burstcoin/jminer/core/network/Network.java index f6978f6..7402509 100644 --- a/src/main/java/burstcoin/jminer/core/network/Network.java +++ b/src/main/java/burstcoin/jminer/core/network/Network.java @@ -28,6 +28,7 @@ import burstcoin.jminer.core.network.task.NetworkRequestLastWinnerTask; import burstcoin.jminer.core.network.task.NetworkRequestMiningInfoTask; import burstcoin.jminer.core.network.task.NetworkRequestPoolInfoTask; +import burstcoin.jminer.core.network.task.NetworkRequestTriggerServerTask; import burstcoin.jminer.core.network.task.NetworkSubmitDevPoolNoncesTask; import burstcoin.jminer.core.network.task.NetworkSubmitPoolNonceTask; import burstcoin.jminer.core.network.task.NetworkSubmitSoloNonceTask; @@ -146,6 +147,17 @@ public void checkNetworkState() } } + // ensure wallet-server does not stuck on solo mining + public void triggerServer() + { + if(!StringUtils.isEmpty(soloServer)) + { + NetworkRequestTriggerServerTask networkRequestTriggerServerTask = context.getBean(NetworkRequestTriggerServerTask.class); + networkRequestTriggerServerTask.init(soloServer, numericAccountId, connectionTimeout); + networkPool.execute(networkRequestTriggerServerTask); + } + } + public void checkLastWinner(long blockNumber) { // find winner of lastBlock on new round, if server available @@ -213,5 +225,18 @@ public void run() checkNetworkState(); } }, 100, CoreProperties.getRefreshInterval()); + + // on solo mining + if(!CoreProperties.isPoolMining()) + { + timer.schedule(new TimerTask() + { + @Override + public void run() + { + triggerServer(); + } + }, 5000, 25000); + } } } diff --git a/src/main/java/burstcoin/jminer/core/network/task/NetworkRequestMiningInfoTask.java b/src/main/java/burstcoin/jminer/core/network/task/NetworkRequestMiningInfoTask.java index 40ad37d..1cd7bb1 100644 --- a/src/main/java/burstcoin/jminer/core/network/task/NetworkRequestMiningInfoTask.java +++ b/src/main/java/burstcoin/jminer/core/network/task/NetworkRequestMiningInfoTask.java @@ -65,16 +65,6 @@ public class NetworkRequestMiningInfoTask private long defaultTargetDeadline; private boolean devV2Pool; - /** - * Init void. - * - * @param server the server - * @param blockNumber the block number - * @param poolMining the pool mining - * @param connectionTimeout the connection timeout - * @param defaultTargetDeadline the default target deadline - * @param devV2Pool the dev v 2 pool - */ public void init(String server, long blockNumber, boolean poolMining, long connectionTimeout, long defaultTargetDeadline, boolean devV2Pool) { this.server = server; @@ -89,6 +79,8 @@ public void init(String server, long blockNumber, boolean poolMining, long conne @Override public void run() { + LOG.trace("start check network state"); + MiningInfoResponse result; try { @@ -123,6 +115,10 @@ public void run() publisher.publishEvent(new NetworkStateChangeEvent(blockNumber, baseTarget, generationSignature, targetDeadline)); } + else + { + LOG.trace("not publish NetworkStateChangeEvent ... '" + blockNumber + " <= " + this.blockNumber + "'"); + } } else { @@ -131,7 +127,7 @@ public void run() } catch(TimeoutException timeoutException) { - LOG.warn("Unable to get mining info from wallet, caused by connectionTimeout, currently '" + (connectionTimeout/1000) + " sec.' try increasing it!"); + LOG.warn("Unable to get mining info from wallet, caused by connectionTimeout, currently '" + (connectionTimeout / 1000) + " sec.' try increasing it!"); } catch(Exception e) { diff --git a/src/main/java/burstcoin/jminer/core/network/task/NetworkRequestTriggerServerTask.java b/src/main/java/burstcoin/jminer/core/network/task/NetworkRequestTriggerServerTask.java new file mode 100644 index 0000000..64e3186 --- /dev/null +++ b/src/main/java/burstcoin/jminer/core/network/task/NetworkRequestTriggerServerTask.java @@ -0,0 +1,111 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016 by luxe - https://github.com/de-luxe - BURST-LUXE-RED2-G6JW-H4HG5 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software + * is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies + * or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package burstcoin.jminer.core.network.task; + +import burstcoin.jminer.core.network.model.BlockchainStatus; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.api.ContentResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.Random; +import java.util.concurrent.TimeUnit; + +/** + * task for solo mining, to ensure that even if wallet ui not open in browser, server does not stuck (helped in my case ... does not hurt). + */ +@Component +@Scope("prototype") +public class NetworkRequestTriggerServerTask + implements Runnable +{ + private static final Logger LOG = LoggerFactory.getLogger(NetworkRequestTriggerServerTask.class); + + @Autowired + private HttpClient httpClient; + + @Autowired + private ObjectMapper objectMapper; + + // data + private String numericAccountId; + private String server; + private long connectionTimeout; + + public void init(String server, String numericAccountId, long connectionTimeout) + { + this.server = server; + this.numericAccountId = numericAccountId; + this.connectionTimeout = connectionTimeout; + } + + @Override + public void run() + { + // imitate requests done by wallet + getBlockChainStatus(); + getUnconfirmedTransactions(numericAccountId); + LOG.trace("wallet server triggered!"); + } + + private BlockchainStatus getBlockChainStatus() + { + BlockchainStatus blockchainStatus = null; + try + { + ContentResponse response = httpClient.newRequest(server + "/burst?requestType=getBlockchainStatus&random=" + new Random().nextFloat()) + .timeout(connectionTimeout, TimeUnit.MILLISECONDS) + .send(); + + blockchainStatus = objectMapper.readValue(response.getContentAsString(), BlockchainStatus.class); + } + catch(Exception e) + { + LOG.warn("Error: Failed to 'getBlockchainStatus' from 'soloServer' to trigger server."); + } + return blockchainStatus; + } + + private void getUnconfirmedTransactions(String numericAccountId) + { + try + { + ContentResponse response = httpClient + .newRequest(server + "/burst?requestType=getUnconfirmedTransactions&accountId=" + numericAccountId + "&random=" + new Random().nextFloat()) + .timeout(connectionTimeout, TimeUnit.MILLISECONDS) + .send(); + + String contentAsString = response.getContentAsString(); + + LOG.trace(contentAsString); + } + catch(Exception e) + { + LOG.warn("Error: Failed to 'getUnconfirmedTransactions' to trigger server."); + } + } +} diff --git a/src/main/java/burstcoin/jminer/core/network/task/NetworkSubmitPoolNonceTask.java b/src/main/java/burstcoin/jminer/core/network/task/NetworkSubmitPoolNonceTask.java index 483db26..9653cc1 100644 --- a/src/main/java/burstcoin/jminer/core/network/task/NetworkSubmitPoolNonceTask.java +++ b/src/main/java/burstcoin/jminer/core/network/task/NetworkSubmitPoolNonceTask.java @@ -52,7 +52,7 @@ public class NetworkSubmitPoolNonceTask implements Runnable { private static final Logger LOG = LoggerFactory.getLogger(NetworkSubmitPoolNonceTask.class); - private static final String HEADER_MINER_NAME = "burstcoin-jminer-0.4.3-SNAPSHOT"; + private static final String HEADER_MINER_NAME = "burstcoin-jminer-0.4.4-SNAPSHOT"; @Autowired private ApplicationEventPublisher publisher; diff --git a/src/main/java/burstcoin/jminer/core/reader/Reader.java b/src/main/java/burstcoin/jminer/core/reader/Reader.java index 472b8e7..c0b3127 100644 --- a/src/main/java/burstcoin/jminer/core/reader/Reader.java +++ b/src/main/java/burstcoin/jminer/core/reader/Reader.java @@ -40,7 +40,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Scope; import org.springframework.context.event.EventListener; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @@ -66,9 +65,6 @@ public class Reader @Autowired private ApplicationContext context; - @Autowired - private ApplicationEventPublisher publisher; - @Autowired @Qualifier(value = "readerPool") private ThreadPoolTaskExecutor readerPool; @@ -147,7 +143,7 @@ public void read(long previousBlockNumber, long blockNumber, int scoopNumber, lo if(readerPool.getActiveCount() > 0) { long elapsedTime = new Date().getTime() - readerStartTime; - publisher.publishEvent(new ReaderStoppedEvent(previousBlockNumber, capacity, remainingCapacity, elapsedTime, lastBestCommittedDeadline)); + context.publishEvent(new ReaderStoppedEvent(previousBlockNumber, capacity, remainingCapacity, elapsedTime, lastBestCommittedDeadline)); } // update reader thread count @@ -207,7 +203,7 @@ public void handleMessage(ReaderLoadedPartEvent event) { remainingCapacity -= removedCapacity; long elapsedTime = new Date().getTime() - readerStartTime; - publisher.publishEvent(new ReaderProgressChangedEvent(this, event.getBlockNumber(), capacity, remainingCapacity, elapsedTime)); + context.publishEvent(new ReaderProgressChangedEvent(this, event.getBlockNumber(), capacity, remainingCapacity, elapsedTime)); } else { @@ -232,7 +228,7 @@ public void handleMessage(NetworkResultErrorEvent event) if(plotFile != null) { // plotFile.toString is just objId - publisher.publishEvent(new ReaderCorruptFileEvent(this, event.getBlockNumber(), plotFile.getFilePath().toString(), plotFile.getNumberOfChunks(), + context.publishEvent(new ReaderCorruptFileEvent(this, event.getBlockNumber(), plotFile.getFilePath().toString(), plotFile.getNumberOfChunks(), plotFile.getNumberOfParts())); } } diff --git a/src/main/java/burstcoin/jminer/core/reader/data/PlotDrive.java b/src/main/java/burstcoin/jminer/core/reader/data/PlotDrive.java index 46bad29..9ebd214 100644 --- a/src/main/java/burstcoin/jminer/core/reader/data/PlotDrive.java +++ b/src/main/java/burstcoin/jminer/core/reader/data/PlotDrive.java @@ -37,7 +37,7 @@ */ public class PlotDrive { - private static final Logger LOGGER = LoggerFactory.getLogger(PlotDrive.class); + private static final Logger LOG = LoggerFactory.getLogger(PlotDrive.class); private Collection plotFiles; private String directory; @@ -61,7 +61,7 @@ public PlotDrive(String directory, Collection plotFilePaths, Long chunkPar if(plotFile.getStaggeramt() % plotFile.getNumberOfParts() != 0) { - LOGGER.warn("could not calculate valid numberOfParts: " + plotFile.getFilePath()); + LOG.warn("could not calculate valid numberOfParts: " + plotFile.getFilePath()); } } } @@ -100,8 +100,7 @@ public Map collectChunkPartStartNonces() chunkPartStartNonces.putAll(plotFile.getChunkPartStartNonces()); if(expectedSize != chunkPartStartNonces.size()) { - LOGGER - .error("possible overlapping plot-file '" + plotFile.getFilePath() + "' please use 'https://bchain.info/BURST/tools/overlap' to check your plots."); + LOG.error("possible overlapping plot-file '" + plotFile.getFilePath() + "' please use 'https://bchain.info/BURST/tools/overlap' to check your plots."); } } return chunkPartStartNonces; diff --git a/src/main/java/burstcoin/jminer/core/reader/data/PlotFile.java b/src/main/java/burstcoin/jminer/core/reader/data/PlotFile.java index fa7800b..a1d9020 100644 --- a/src/main/java/burstcoin/jminer/core/reader/data/PlotFile.java +++ b/src/main/java/burstcoin/jminer/core/reader/data/PlotFile.java @@ -27,8 +27,6 @@ import org.slf4j.LoggerFactory; import pocminer.generate.MiningPlot; -import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; import java.util.Map; @@ -38,7 +36,7 @@ */ public class PlotFile { - private static final Logger LOGGER = LoggerFactory.getLogger(PlotFile.class); + private static final Logger LOG = LoggerFactory.getLogger(PlotFile.class); // key -> size private Map chunkPartStartNonces; @@ -59,7 +57,7 @@ public class PlotFile /** * Instantiates a new Plot file. * - * @param filePath the file path + * @param filePath the file path * @param chunkPartNonces the chunk part nonces */ public PlotFile(Path filePath, Long chunkPartNonces) @@ -78,7 +76,17 @@ public PlotFile(Path filePath, Long chunkPartNonces) chunkPartStartNonces = new HashMap<>(); size = numberOfChunks * staggeramt * MiningPlot.PLOT_SIZE; - long chunkPartSize = size / numberOfChunks / numberOfParts; + + if(LOG.isDebugEnabled()) + { + long fileSize = filePath.toFile().length(); + if(fileSize != size) + { + LOG.debug("incomplete plotFile: " + filePath.toString() + " specified size '" + size + " bytes', size '" + fileSize + " bytes'."); + } + } + + long chunkPartSize = this.size / numberOfChunks / numberOfParts; for(int chunkNumber = 0; chunkNumber < numberOfChunks; chunkNumber++) { for(int partNumber = 0; partNumber < numberOfParts; partNumber++) @@ -88,26 +96,12 @@ public PlotFile(Path filePath, Long chunkPartNonces) Long key = chunkPartStartNonces.put(chunkPartStartNonce, chunkPartSize); if(key != null) { - LOGGER.error("possible overlapping plot-file '" + filePath + "' please use 'https://bchain.info/BURST/tools/overlap' to check your plots."); + LOG.error("possible overlapping plot-file '" + filePath + "' please use 'https://bchain.info/BURST/tools/overlap' to check your plots."); } } } } - private long getSize(Path filePath) - { - long size = 1; - try - { - size = Files.size(filePath); - } - catch(IOException e) - { - e.printStackTrace(); - } - return size; - } - /** * Gets size. * diff --git a/src/main/java/burstcoin/jminer/core/reader/data/Plots.java b/src/main/java/burstcoin/jminer/core/reader/data/Plots.java index 467af7d..c01b79d 100644 --- a/src/main/java/burstcoin/jminer/core/reader/data/Plots.java +++ b/src/main/java/burstcoin/jminer/core/reader/data/Plots.java @@ -23,6 +23,7 @@ package burstcoin.jminer.core.reader.data; +import burstcoin.jminer.core.CoreProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,18 +45,16 @@ */ public class Plots { - private static final Logger LOGGER = LoggerFactory.getLogger(Plots.class); + private static final Logger LOG = LoggerFactory.getLogger(Plots.class); private Collection plotDrives; private Map chunkPartStartNonces; - /** - * Instantiates a new Plots. - * - * @param plotPaths the plot paths - * @param numericAccountId the numeric account id - * @param chunkPartNonces the chunk part nonces - */ + public Plots() + { + this(CoreProperties.getPlotPaths(), CoreProperties.getNumericAccountId(), CoreProperties.getChunkPartNonces()); + } + public Plots(List plotPaths, String numericAccountId, long chunkPartNonces) { plotDrives = new HashSet<>(); @@ -70,8 +69,8 @@ public Plots(List plotPaths, String numericAccountId, long chunkPartNonc chunkPartStartNonces.putAll(plotDrive.collectChunkPartStartNonces()); if(expectedSize != chunkPartStartNonces.size()) { - LOGGER.error("possible duplicate/overlapping polt-file on drive '" + plotDrive.getDirectory() - + "' please use 'https://bchain.info/BURST/tools/overlap' to check your plots."); + LOG.error("possible duplicate/overlapping polt-file on drive '" + plotDrive.getDirectory() + + "' please use 'https://bchain.info/BURST/tools/overlap' to check your plots."); } } } @@ -106,7 +105,7 @@ private static Map> collectPlotFiles(List plotD } catch(IOException | DirectoryIteratorException e) { - LOGGER.error(e.getMessage()); + LOG.error(e.getMessage()); } } return plotFilesLookup; @@ -115,9 +114,8 @@ private static Map> collectPlotFiles(List plotD /** * Gets size. * - * @return the size + * @return total number of bytes of all plotFiles */ -// returns total number of bytes of all plotFiles public long getSize() { long size = 0; @@ -146,6 +144,7 @@ public void printPlotFiles() * Gets plot file by plot file start nonce. * * @param plotFileStartNonce the plot file start nonce + * * @return the plot file by plot file start nonce */ public PlotFile getPlotFileByPlotFileStartNonce(long plotFileStartNonce) @@ -177,6 +176,7 @@ public Map getChunkPartStartNonces() * Gets plot file by chunk part start nonce. * * @param chunkPartStartNonce the chunk part start nonce + * * @return the plot file by chunk part start nonce */ public PlotFile getPlotFileByChunkPartStartNonce(long chunkPartStartNonce) diff --git a/src/main/java/burstcoin/jminer/core/reader/task/ReaderLoadDriveTask.java b/src/main/java/burstcoin/jminer/core/reader/task/ReaderLoadDriveTask.java index af4fc11..7eab1fb 100644 --- a/src/main/java/burstcoin/jminer/core/reader/task/ReaderLoadDriveTask.java +++ b/src/main/java/burstcoin/jminer/core/reader/task/ReaderLoadDriveTask.java @@ -127,7 +127,7 @@ private boolean load(PlotFile plotFile) if(Reader.blockNumber != blockNumber) { - LOG.debug("loadDriveThread stopped!"); + LOG.trace("loadDriveThread stopped!"); partBuffer.clear(); sbc.close(); return true; @@ -150,7 +150,7 @@ private boolean load(PlotFile plotFile) catch(ClosedByInterruptException e) { // we reach this, if we do not wait for task on shutdown - ByteChannel closed by thread interruption - LOG.debug("reader stopped cause of new block ..."); + LOG.trace("reader stopped cause of new block ..."); } catch(IOException e) { diff --git a/src/main/java/burstcoin/jminer/core/round/Round.java b/src/main/java/burstcoin/jminer/core/round/Round.java index 02deeda..d4a15d1 100644 --- a/src/main/java/burstcoin/jminer/core/round/Round.java +++ b/src/main/java/burstcoin/jminer/core/round/Round.java @@ -250,7 +250,7 @@ public void handleMessage(CheckerResultEvent event) } else { - LOG.debug("event for previous block ..."); + LOG.trace("event for previous block ..."); } } @@ -277,7 +277,7 @@ public void handleMessage(CheckerDevResultEvent event) } else { - LOG.debug("event for previous block ..."); + LOG.trace("event for previous block ..."); } } diff --git a/src/main/java/burstcoin/jminer/core/round/task/RoundFireEventTask.java b/src/main/java/burstcoin/jminer/core/round/task/RoundFireEventTask.java index ab83d05..4569732 100644 --- a/src/main/java/burstcoin/jminer/core/round/task/RoundFireEventTask.java +++ b/src/main/java/burstcoin/jminer/core/round/task/RoundFireEventTask.java @@ -31,7 +31,7 @@ import org.springframework.stereotype.Component; /** - * The type Round fire event task. + * ensure event handler code is executed in round pool */ @Component @Scope("prototype") @@ -45,12 +45,6 @@ public class RoundFireEventTask private ApplicationEvent event; - /** - * Init void. - * - * @param the type parameter - * @param event the event - */ public void init(EVENT event) { this.event = event; diff --git a/src/main/java/org/jocl/utils/CommandQueueInfos.java b/src/main/java/org/jocl/utils/CommandQueueInfos.java new file mode 100644 index 0000000..0bcaad3 --- /dev/null +++ b/src/main/java/org/jocl/utils/CommandQueueInfos.java @@ -0,0 +1,123 @@ +/* + * JOCL Utilities + * + * Copyright (c) 2011-2012 Marco Hutter - http://www.jocl.org + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.jocl.utils; + +import org.jocl.cl_command_queue; +import org.jocl.cl_context; +import org.jocl.cl_device_id; + +import static org.jocl.CL.*; + +/** + * Utility methods for obtaining information about cl_command_queue objects + */ +public class CommandQueueInfos +{ + /** + * The context that this command queue belongs to + * + * @param commandQueue The command queue + * + * @return The value + */ + public static cl_context getContext(cl_command_queue commandQueue) + { + cl_context result = new cl_context(); + Infos.getPointer(Infos.FOR_COMMAND_QUEUE, commandQueue, + CL_QUEUE_CONTEXT, result); + if(result.equals(new cl_context())) + { + return null; + } + return result; + } + + /** + * The device that this command queue belongs to + * + * @param commandQueue The command queue + * + * @return The value + */ + public static cl_device_id getDevice(cl_command_queue commandQueue) + { + cl_device_id result = new cl_device_id(); + Infos.getPointer(Infos.FOR_COMMAND_QUEUE, commandQueue, + CL_QUEUE_CONTEXT, result); + if(result.equals(new cl_device_id())) + { + return null; + } + return result; + } + + /** + * The reference count. Only intended for identifying memory leaks. + * + * @param commandQueue The command queue + * + * @return The value + */ + public static int getReferenceCount(cl_command_queue commandQueue) + { + return Infos.getInt(Infos.FOR_COMMAND_QUEUE, commandQueue, + CL_QUEUE_REFERENCE_COUNT); + } + + /** + * The properties of the command queue. + * + * @param commandQueue The command queue + * + * @return The value + */ + public static long getProperties(cl_command_queue commandQueue) + { + return Infos.getLong(Infos.FOR_COMMAND_QUEUE, commandQueue, + CL_QUEUE_PROPERTIES); + } + + /** + * The properties of the command queue, as a String + * + * @param commandQueue The command queue + * + * @return The value + */ + public static String getPropertiesString(cl_command_queue commandQueue) + { + return stringFor_cl_command_queue_properties(getProperties(commandQueue)); + } + + /** + * Private constructor to prevent instantiation + */ + private CommandQueueInfos() + { + } +} diff --git a/src/main/java/org/jocl/utils/CommandQueues.java b/src/main/java/org/jocl/utils/CommandQueues.java new file mode 100644 index 0000000..7a56142 --- /dev/null +++ b/src/main/java/org/jocl/utils/CommandQueues.java @@ -0,0 +1,1119 @@ +/* + * JOCL Utilities + * + * Copyright (c) 2011-2012 Marco Hutter - http://www.jocl.org + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.jocl.utils; + +import org.jocl.Pointer; +import org.jocl.Sizeof; +import org.jocl.cl_command_queue; +import org.jocl.cl_context; +import org.jocl.cl_device_id; +import org.jocl.cl_event; +import org.jocl.cl_kernel; +import org.jocl.cl_mem; + +import java.nio.ByteBuffer; +import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; +import java.util.Arrays; +import java.util.List; + +import static org.jocl.CL.*; + +/** + * Utility methods related to cl_command_queue objects + */ +public class CommandQueues +{ + /** + * Create and return a command queue for the given device. + * + * @param context The context + * @param device The device + * + * @return The command queue + */ + public static cl_command_queue create( + cl_context context, cl_device_id device) + { + return create(context, device, 0); + } + + /** + * Create and return a command queue for the given device. + * + * @param context The context + * @param device The device + * @param profilingEnabled Whether profiling should be enabled + * + * @return The command queue + */ + public static cl_command_queue create( + cl_context context, cl_device_id device, boolean profilingEnabled) + { + return create(context, device, + (profilingEnabled ? CL_QUEUE_PROFILING_ENABLE : 0)); + } + + + /** + * Create and return a command queue for the given device. + * + * @param context The context + * @param device The device + * @param properties The command queue properties + * + * @return The command queue + */ + private static cl_command_queue create( + cl_context context, cl_device_id device, long properties) + { + return clCreateCommandQueue( + context, device, properties, null); + } + + /** + * Create and return an unmodifiable list of command queues, one for each of the given devices. + * + * @param context The context + * @param devices The devices + * + * @return The list of command queues + */ + public static List create( + cl_context context, List devices) + { + return create(context, devices, 0); + } + + /** + * Create and return an unmodifiable list of command queues, one for each of the given devices. + * + * @param context The context + * @param devices The devices + * @param profilingEnabled Whether profiling should be enabled + * + * @return The list of command queues + */ + public static List create( + cl_context context, List devices, boolean profilingEnabled) + { + return create(context, devices, + (profilingEnabled ? CL_QUEUE_PROFILING_ENABLE : 0)); + } + + + /** + * Create and return an unmodifiable list of command queues, one for each of the given devices. + * + * @param context The context + * @param devices The devices + * @param properties The command queue properties + * + * @return The list of command queues + */ + private static List create( + cl_context context, List devices, long properties) + { + cl_command_queue commandQueues[] = + new cl_command_queue[devices.size()]; + for(int i = 0; i < devices.size(); i++) + { + commandQueues[i] = + clCreateCommandQueue( + context, devices.get(i), properties, null); + } + return Arrays.asList(commandQueues); + } + + /** + * Release each of the given command queues if it is not null. + * + * @param commandQueues The command queues to release + */ + public static void release(cl_command_queue... commandQueues) + { + if(commandQueues != null) + { + release(Arrays.asList(commandQueues)); + } + } + + /** + * Release each of the given command queues if it is not null. + * + * @param commandQueues The command queues to release + */ + public static void release(Iterable commandQueues) + { + if(commandQueues != null) + { + for(cl_command_queue commandQueue : commandQueues) + { + if(commandQueue != null) + { + clReleaseCommandQueue(commandQueue); + } + } + } + } + + + /** + * Finish each of the given command queues if it is not null. + * + * @param commandQueues The command queues to finish + */ + public static void finish(cl_command_queue... commandQueues) + { + if(commandQueues != null) + { + finish(Arrays.asList(commandQueues)); + } + } + + /** + * Finish each of the given command queues if it is not null. + * + * @param commandQueues The command queues to finish + */ + public static void finish(Iterable commandQueues) + { + if(commandQueues != null) + { + for(cl_command_queue commandQueue : commandQueues) + { + if(commandQueue != null) + { + clFinish(commandQueue); + } + } + } + } + + //=== Kernel enqueueing ================================================== + + /** + * Enqueue the given kernel as a 1D kernel to the given command queue, using the given global work size. + * + * @param commandQueue The command queue + * @param kernel The kernel to enqueue + * @param globalSizeX The global work size + */ + public static void enqueueKernel1D( + cl_command_queue commandQueue, cl_kernel kernel, + long globalSizeX) + { + clEnqueueNDRangeKernel(commandQueue, kernel, 1, null, + new long[]{globalSizeX}, + null, + 0, null, null); + } + + /** + * Enqueue the given kernel as a 1D kernel to the given command queue, using the given global and local work size. + * + * @param commandQueue The command queue + * @param kernel The kernel to enqueue + * @param globalSizeX The global work size + * @param localSizeX The local work size + */ + public static void enqueueKernel1D( + cl_command_queue commandQueue, cl_kernel kernel, + long globalSizeX, long localSizeX) + { + clEnqueueNDRangeKernel(commandQueue, kernel, 1, null, + new long[]{globalSizeX}, + new long[]{localSizeX}, + 0, null, null); + } + + /** + * Enqueue the given kernel as a 2D kernel to the given command queue, using the given global work sizes. + * + * @param commandQueue The command queue + * @param kernel The kernel to enqueue + * @param globalSizeX The global work size for dimension 0 + * @param globalSizeY The global work size for dimension 1 + */ + public static void enqueueKernel2D( + cl_command_queue commandQueue, cl_kernel kernel, + long globalSizeX, long globalSizeY) + { + clEnqueueNDRangeKernel(commandQueue, kernel, 2, null, + new long[]{globalSizeX, globalSizeY}, + null, + 0, null, null); + } + + /** + * Enqueue the given kernel as a 2D kernel to the given command queue, using the given global and local work sizes. + * + * @param commandQueue The command queue + * @param kernel The kernel to enqueue + * @param globalSizeX The global work size for dimension 0 + * @param globalSizeY The global work size for dimension 1 + * @param localSizeX The local work size for dimension 0 + * @param localSizeY The local work size for dimension 1 + */ + public static void enqueueKernel2D( + cl_command_queue commandQueue, cl_kernel kernel, + long globalSizeX, long globalSizeY, + long localSizeX, long localSizeY) + { + clEnqueueNDRangeKernel(commandQueue, kernel, 2, null, + new long[]{globalSizeX, globalSizeY}, + new long[]{localSizeX, localSizeY}, + 0, null, null); + } + + /** + * Enqueue the given kernel as a 3D kernel to the given command queue, using the given global work sizes. + * + * @param commandQueue The command queue + * @param kernel The kernel to enqueue + * @param globalSizeX The global work size for dimension 0 + * @param globalSizeY The global work size for dimension 1 + * @param globalSizeZ The global work size for dimension 2 + */ + public static void enqueueKernel3D( + cl_command_queue commandQueue, cl_kernel kernel, + long globalSizeX, long globalSizeY, long globalSizeZ) + { + clEnqueueNDRangeKernel(commandQueue, kernel, 3, null, + new long[]{globalSizeX, globalSizeY, globalSizeZ}, + null, + 0, null, null); + } + + /** + * Enqueue the given kernel as a 3D kernel to the given command queue, using the given global and local work sizes. + * + * @param commandQueue The command queue + * @param kernel The kernel to enqueue + * @param globalSizeX The global work size for dimension 0 + * @param globalSizeY The global work size for dimension 1 + * @param globalSizeZ The global work size for dimension 2 + * @param localSizeX The local work size for dimension 0 + * @param localSizeY The local work size for dimension 1 + * @param localSizeZ The local work size for dimension 2 + */ + public static void enqueueKernel3D( + cl_command_queue commandQueue, cl_kernel kernel, + long globalSizeX, long globalSizeY, long globalSizeZ, + long localSizeX, long localSizeY, long localSizeZ) + { + clEnqueueNDRangeKernel(commandQueue, kernel, 3, null, + new long[]{globalSizeX, globalSizeY, globalSizeZ}, + new long[]{localSizeX, localSizeY, localSizeZ}, + 0, null, null); + } + + /** + * Enqueue the given kernel as a n-D kernel to the given command queue, using the given global and local work sizes. + * + * @param commandQueue The command queue + * @param kernel The kernel to enqueue + * @param n The dimension of the kernel + * @param globalSize The global work size + * @param localSize The local work size + */ + public static void enqueueKernelND( + cl_command_queue commandQueue, cl_kernel kernel, int n, + long globalSize[], long localSize[]) + { + clEnqueueNDRangeKernel(commandQueue, kernel, n, null, + globalSize, + localSize, + 0, null, null); + } + + + //=== Kernel enqueueing with events ====================================== + + /** + * Enqueue the given kernel as a 1D kernel to the given command queue, using the given global work size. + * + * @param commandQueue The command queue + * @param kernel The kernel to enqueue + * @param globalSizeX The global work size + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueKernel1D( + cl_command_queue commandQueue, cl_kernel kernel, + long globalSizeX, + List waitList, cl_event event) + { + clEnqueueNDRangeKernel(commandQueue, kernel, 1, null, + new long[]{globalSizeX}, + null, + sizeOf(waitList), asArray(waitList), event); + } + + /** + * Enqueue the given kernel as a 1D kernel to the given command queue, using the given global and local work size. + * + * @param commandQueue The command queue + * @param kernel The kernel to enqueue + * @param globalSizeX The global work size + * @param localSizeX The local work size + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueKernel1D( + cl_command_queue commandQueue, cl_kernel kernel, + long globalSizeX, long localSizeX, + List waitList, cl_event event) + { + clEnqueueNDRangeKernel(commandQueue, kernel, 1, null, + new long[]{globalSizeX}, + new long[]{localSizeX}, + sizeOf(waitList), asArray(waitList), event); + } + + /** + * Enqueue the given kernel as a 2D kernel to the given command queue, using the given global work sizes. + * + * @param commandQueue The command queue + * @param kernel The kernel to enqueue + * @param globalSizeX The global work size for dimension 0 + * @param globalSizeY The global work size for dimension 1 + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueKernel2D( + cl_command_queue commandQueue, cl_kernel kernel, + long globalSizeX, long globalSizeY, + List waitList, cl_event event) + { + clEnqueueNDRangeKernel(commandQueue, kernel, 2, null, + new long[]{globalSizeX, globalSizeY}, + null, + sizeOf(waitList), asArray(waitList), event); + } + + /** + * Enqueue the given kernel as a 2D kernel to the given command queue, using the given global and local work sizes. + * + * @param commandQueue The command queue + * @param kernel The kernel to enqueue + * @param globalSizeX The global work size for dimension 0 + * @param globalSizeY The global work size for dimension 1 + * @param localSizeX The local work size for dimension 0 + * @param localSizeY The local work size for dimension 1 + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueKernel2D( + cl_command_queue commandQueue, cl_kernel kernel, + long globalSizeX, long globalSizeY, + long localSizeX, long localSizeY, + List waitList, cl_event event) + { + clEnqueueNDRangeKernel(commandQueue, kernel, 2, null, + new long[]{globalSizeX, globalSizeY}, + new long[]{localSizeX, localSizeY}, + sizeOf(waitList), asArray(waitList), event); + } + + /** + * Enqueue the given kernel as a 3D kernel to the given command queue, using the given global work sizes. + * + * @param commandQueue The command queue + * @param kernel The kernel to enqueue + * @param globalSizeX The global work size for dimension 0 + * @param globalSizeY The global work size for dimension 1 + * @param globalSizeZ The global work size for dimension 2 + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueKernel3D( + cl_command_queue commandQueue, cl_kernel kernel, + long globalSizeX, long globalSizeY, long globalSizeZ, + List waitList, cl_event event) + { + clEnqueueNDRangeKernel(commandQueue, kernel, 3, null, + new long[]{globalSizeX, globalSizeY, globalSizeZ}, + null, + sizeOf(waitList), asArray(waitList), event); + } + + /** + * Enqueue the given kernel as a 3D kernel to the given command queue, using the given global and local work sizes. + * + * @param commandQueue The command queue + * @param kernel The kernel to enqueue + * @param globalSizeX The global work size for dimension 0 + * @param globalSizeY The global work size for dimension 1 + * @param globalSizeZ The global work size for dimension 2 + * @param localSizeX The local work size for dimension 0 + * @param localSizeY The local work size for dimension 1 + * @param localSizeZ The local work size for dimension 2 + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueKernel3D( + cl_command_queue commandQueue, cl_kernel kernel, + long globalSizeX, long globalSizeY, long globalSizeZ, + long localSizeX, long localSizeY, long localSizeZ, + List waitList, cl_event event) + { + clEnqueueNDRangeKernel(commandQueue, kernel, 3, null, + new long[]{globalSizeX, globalSizeY, globalSizeZ}, + new long[]{localSizeX, localSizeY, localSizeZ}, + sizeOf(waitList), asArray(waitList), event); + } + + /** + * Enqueue the given kernel as a n-D kernel to the given command queue, using the given global and local work sizes. + * + * @param commandQueue The command queue + * @param kernel The kernel to enqueue + * @param n The dimension of the kernel + * @param globalSize The global work size + * @param localSize The local work size. May be null. + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueKernelND( + cl_command_queue commandQueue, cl_kernel kernel, int n, + long globalSize[], long localSize[], + List waitList, cl_event event) + { + clEnqueueNDRangeKernel(commandQueue, kernel, n, null, + globalSize, + localSize, + 0, null, null); + //sizeOf(waitList), asArray(waitList), event); + } + + + //=== Read/write buffers (char) ========================================== + + /** + * Enqueue a command to read the given buffer into the given target Buffer. This command will be blocking if and only if the target Buffer is a not a + * direct buffer. The size of the data transfer will be computed from the position and limit of the given Buffer. + * + * @param commandQueue The command queue + * @param buffer The source buffer + * @param target The target Buffer + */ + public static void enqueueReadBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + ByteBuffer target) + { + enqueueReadBuffer(commandQueue, buffer, 0, target, + !target.isDirect(), null, null); + } + + /** + * Enqueue a command to read the given buffer into the given target Buffer. The size of the data transfer will be computed from the position and limit of the + * given Buffer. + * + * @param commandQueue The command queue + * @param buffer The source buffer + * @param sourceOffset The offset (in number of elements) in the source buffer + * @param target The target Buffer + * @param blocking Whether the transfer should be blocking + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueReadBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + long sourceOffset, + ByteBuffer target, + boolean blocking, + List waitList, cl_event event) + { + Pointer targetPointer = PointerUtils.toBuffer(target); + clEnqueueReadBuffer(commandQueue, buffer, blocking, + sourceOffset * Sizeof.cl_char, + target.remaining() * Sizeof.cl_char, targetPointer, + sizeOf(waitList), asArray(waitList), event); + } + + + /** + * Enqueue a command to write the given buffer from the given source Buffer. This command will be blocking if and only if the source Buffer is a not a + * direct buffer. The size of the data transfer will be computed from the position and limit of the given Buffer. + * + * @param commandQueue The command queue + * @param buffer The target buffer + * @param source The source Buffer + */ + public static void enqueueWriteBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + ByteBuffer source) + { + enqueueWriteBuffer(commandQueue, buffer, 0, source, + !source.isDirect(), null, null); + } + + /** + * Enqueue a command to write the given buffer from the given source Buffer. The size of the data transfer will be computed from the position and limit of the + * given Buffer. + * + * @param commandQueue The command queue + * @param buffer The target buffer + * @param targetOffset The offset (in number of elements) in the target buffer + * @param source The source Buffer + * @param blocking Whether the transfer should be blocking + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueWriteBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + long targetOffset, + ByteBuffer source, + boolean blocking, + List waitList, cl_event event) + { + Pointer sourcePointer = PointerUtils.toBuffer(source); + clEnqueueWriteBuffer(commandQueue, buffer, blocking, + targetOffset * Sizeof.cl_char, + source.remaining() * Sizeof.cl_char, sourcePointer, + sizeOf(waitList), asArray(waitList), event); + } + + + //=== Read/write buffers (short) ========================================== + + /** + * Enqueue a command to read the given buffer into the given target Buffer. This command will be blocking if and only if the target Buffer is a not a + * direct buffer. The size of the data transfer will be computed from the position and limit of the given Buffer. + * + * @param commandQueue The command queue + * @param buffer The source buffer + * @param target The target Buffer + */ + public static void enqueueReadBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + ShortBuffer target) + { + enqueueReadBuffer(commandQueue, buffer, 0, target, + !target.isDirect(), null, null); + } + + /** + * Enqueue a command to read the given buffer into the given target Buffer. The size of the data transfer will be computed from the position and limit of the + * given Buffer. + * + * @param commandQueue The command queue + * @param buffer The source buffer + * @param sourceOffset The offset (in number of elements) in the source buffer + * @param target The target Buffer + * @param blocking Whether the transfer should be blocking + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueReadBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + long sourceOffset, + ShortBuffer target, + boolean blocking, + List waitList, cl_event event) + { + Pointer targetPointer = PointerUtils.toBuffer(target); + clEnqueueReadBuffer(commandQueue, buffer, blocking, + sourceOffset * Sizeof.cl_short, + target.remaining() * Sizeof.cl_short, targetPointer, + sizeOf(waitList), asArray(waitList), event); + } + + + /** + * Enqueue a command to write the given buffer from the given source Buffer. This command will be blocking if and only if the source Buffer is a not a + * direct buffer. The size of the data transfer will be computed from the position and limit of the given Buffer. + * + * @param commandQueue The command queue + * @param buffer The target buffer + * @param source The source Buffer + */ + public static void enqueueWriteBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + ShortBuffer source) + { + enqueueWriteBuffer(commandQueue, buffer, 0, source, + !source.isDirect(), null, null); + } + + /** + * Enqueue a command to write the given buffer from the given source Buffer. The size of the data transfer will be computed from the position and limit of the + * given Buffer. + * + * @param commandQueue The command queue + * @param buffer The target buffer + * @param targetOffset The offset (in number of elements) in the target buffer + * @param source The source Buffer + * @param blocking Whether the transfer should be blocking + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueWriteBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + long targetOffset, + ShortBuffer source, + boolean blocking, + List waitList, cl_event event) + { + Pointer sourcePointer = PointerUtils.toBuffer(source); + clEnqueueWriteBuffer(commandQueue, buffer, blocking, + targetOffset * Sizeof.cl_short, + source.remaining() * Sizeof.cl_short, sourcePointer, + sizeOf(waitList), asArray(waitList), event); + } + + + //=== Read/write buffers (int) ========================================== + + /** + * Enqueue a command to read the given buffer into the given target Buffer. This command will be blocking if and only if the target Buffer is a not a + * direct buffer. The size of the data transfer will be computed from the position and limit of the given Buffer. + * + * @param commandQueue The command queue + * @param buffer The source buffer + * @param target The target Buffer + */ + public static void enqueueReadBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + IntBuffer target) + { + enqueueReadBuffer(commandQueue, buffer, 0, target, + !target.isDirect(), null, null); + } + + /** + * Enqueue a command to read the given buffer into the given target Buffer. The size of the data transfer will be computed from the position and limit of the + * given Buffer. + * + * @param commandQueue The command queue + * @param buffer The source buffer + * @param sourceOffset The offset (in number of elements) in the source buffer + * @param target The target Buffer + * @param blocking Whether the transfer should be blocking + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueReadBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + long sourceOffset, + IntBuffer target, + boolean blocking, + List waitList, cl_event event) + { + Pointer targetPointer = PointerUtils.toBuffer(target); + clEnqueueReadBuffer(commandQueue, buffer, blocking, + sourceOffset * Sizeof.cl_int, + target.remaining() * Sizeof.cl_int, targetPointer, + sizeOf(waitList), asArray(waitList), event); + } + + + /** + * Enqueue a command to write the given buffer from the given source Buffer. This command will be blocking if and only if the source Buffer is a not a + * direct buffer. The size of the data transfer will be computed from the position and limit of the given Buffer. + * + * @param commandQueue The command queue + * @param buffer The target buffer + * @param source The source Buffer + */ + public static void enqueueWriteBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + IntBuffer source) + { + enqueueWriteBuffer(commandQueue, buffer, 0, source, + !source.isDirect(), null, null); + } + + /** + * Enqueue a command to write the given buffer from the given source Buffer. The size of the data transfer will be computed from the position and limit of the + * given Buffer. + * + * @param commandQueue The command queue + * @param buffer The target buffer + * @param targetOffset The offset (in number of elements) in the target buffer + * @param source The source Buffer + * @param blocking Whether the transfer should be blocking + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueWriteBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + long targetOffset, + IntBuffer source, + boolean blocking, + List waitList, cl_event event) + { + Pointer sourcePointer = PointerUtils.toBuffer(source); + clEnqueueWriteBuffer(commandQueue, buffer, blocking, + targetOffset * Sizeof.cl_int, + source.remaining() * Sizeof.cl_int, sourcePointer, + sizeOf(waitList), asArray(waitList), event); + } + + + //=== Read/write buffers (long) ========================================== + + /** + * Enqueue a command to read the given buffer into the given target Buffer. This command will be blocking if and only if the target Buffer is a not a + * direct buffer. The size of the data transfer will be computed from the position and limit of the given Buffer. + * + * @param commandQueue The command queue + * @param buffer The source buffer + * @param target The target Buffer + */ + public static void enqueueReadBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + LongBuffer target) + { + enqueueReadBuffer(commandQueue, buffer, 0, target, + !target.isDirect(), null, null); + } + + /** + * Enqueue a command to read the given buffer into the given target Buffer. The size of the data transfer will be computed from the position and limit of the + * given Buffer. + * + * @param commandQueue The command queue + * @param buffer The source buffer + * @param sourceOffset The offset (in number of elements) in the source buffer + * @param target The target Buffer + * @param blocking Whether the transfer should be blocking + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueReadBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + long sourceOffset, + LongBuffer target, + boolean blocking, + List waitList, cl_event event) + { + Pointer targetPointer = PointerUtils.toBuffer(target); + clEnqueueReadBuffer(commandQueue, buffer, blocking, + sourceOffset * Sizeof.cl_long, + target.remaining() * Sizeof.cl_long, targetPointer, + sizeOf(waitList), asArray(waitList), event); + } + + + /** + * Enqueue a command to write the given buffer from the given source Buffer. This command will be blocking if and only if the source Buffer is a not a + * direct buffer. The size of the data transfer will be computed from the position and limit of the given Buffer. + * + * @param commandQueue The command queue + * @param buffer The target buffer + * @param source The source Buffer + */ + public static void enqueueWriteBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + LongBuffer source) + { + enqueueWriteBuffer(commandQueue, buffer, 0, source, + !source.isDirect(), null, null); + } + + /** + * Enqueue a command to write the given buffer from the given source Buffer. The size of the data transfer will be computed from the position and limit of the + * given Buffer. + * + * @param commandQueue The command queue + * @param buffer The target buffer + * @param targetOffset The offset (in number of elements) in the target buffer + * @param source The source Buffer + * @param blocking Whether the transfer should be blocking + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueWriteBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + long targetOffset, + LongBuffer source, + boolean blocking, + List waitList, cl_event event) + { + Pointer sourcePointer = PointerUtils.toBuffer(source); + clEnqueueWriteBuffer(commandQueue, buffer, blocking, + targetOffset * Sizeof.cl_long, + source.remaining() * Sizeof.cl_long, sourcePointer, + sizeOf(waitList), asArray(waitList), event); + } + + + //=== Read/write buffers (float) ========================================== + + /** + * Enqueue a command to read the given buffer into the given target Buffer. This command will be blocking if and only if the target Buffer is a not a + * direct buffer. The size of the data transfer will be computed from the position and limit of the given Buffer. + * + * @param commandQueue The command queue + * @param buffer The source buffer + * @param target The target Buffer + */ + public static void enqueueReadBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + FloatBuffer target) + { + enqueueReadBuffer(commandQueue, buffer, 0, target, + !target.isDirect(), null, null); + } + + /** + * Enqueue a command to read the given buffer into the given target Buffer. The size of the data transfer will be computed from the position and limit of the + * given Buffer. + * + * @param commandQueue The command queue + * @param buffer The source buffer + * @param sourceOffset The offset (in number of elements) in the source buffer + * @param target The target Buffer + * @param blocking Whether the transfer should be blocking + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueReadBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + long sourceOffset, + FloatBuffer target, + boolean blocking, + List waitList, cl_event event) + { + Pointer targetPointer = PointerUtils.toBuffer(target); + clEnqueueReadBuffer(commandQueue, buffer, blocking, + sourceOffset * Sizeof.cl_float, + target.remaining() * Sizeof.cl_float, targetPointer, + sizeOf(waitList), asArray(waitList), event); + } + + + /** + * Enqueue a command to write the given buffer from the given source Buffer. This command will be blocking if and only if the source Buffer is a not a + * direct buffer. The size of the data transfer will be computed from the position and limit of the given Buffer. + * + * @param commandQueue The command queue + * @param buffer The target buffer + * @param source The source Buffer + */ + public static void enqueueWriteBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + FloatBuffer source) + { + enqueueWriteBuffer(commandQueue, buffer, 0, source, + !source.isDirect(), null, null); + } + + /** + * Enqueue a command to write the given buffer from the given source Buffer. The size of the data transfer will be computed from the position and limit of the + * given Buffer. + * + * @param commandQueue The command queue + * @param buffer The target buffer + * @param targetOffset The offset (in number of elements) in the target buffer + * @param source The source Buffer + * @param blocking Whether the transfer should be blocking + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueWriteBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + long targetOffset, + FloatBuffer source, + boolean blocking, + List waitList, cl_event event) + { + Pointer sourcePointer = PointerUtils.toBuffer(source); + clEnqueueWriteBuffer(commandQueue, buffer, blocking, + targetOffset * Sizeof.cl_float, + source.remaining() * Sizeof.cl_float, sourcePointer, + sizeOf(waitList), asArray(waitList), event); + } + + + //=== Read/write buffers (double) ========================================== + + /** + * Enqueue a command to read the given buffer into the given target Buffer. This command will be blocking if and only if the target Buffer is a not a + * direct buffer. The size of the data transfer will be computed from the position and limit of the given Buffer. + * + * @param commandQueue The command queue + * @param buffer The source buffer + * @param target The target Buffer + */ + public static void enqueueReadBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + DoubleBuffer target) + { + enqueueReadBuffer(commandQueue, buffer, 0, target, + !target.isDirect(), null, null); + } + + /** + * Enqueue a command to read the given buffer into the given target Buffer. The size of the data transfer will be computed from the position and limit of the + * given Buffer. + * + * @param commandQueue The command queue + * @param buffer The source buffer + * @param sourceOffset The offset (in number of elements) in the source buffer + * @param target The target Buffer + * @param blocking Whether the transfer should be blocking + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueReadBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + long sourceOffset, + DoubleBuffer target, + boolean blocking, + List waitList, cl_event event) + { + Pointer targetPointer = PointerUtils.toBuffer(target); + clEnqueueReadBuffer(commandQueue, buffer, blocking, + sourceOffset * Sizeof.cl_double, + target.remaining() * Sizeof.cl_double, targetPointer, + sizeOf(waitList), asArray(waitList), event); + } + + + /** + * Enqueue a command to write the given buffer from the given source Buffer. This command will be blocking if and only if the source Buffer is a not a + * direct buffer. The size of the data transfer will be computed from the position and limit of the given Buffer. + * + * @param commandQueue The command queue + * @param buffer The target buffer + * @param source The source Buffer + */ + public static void enqueueWriteBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + DoubleBuffer source) + { + enqueueWriteBuffer(commandQueue, buffer, 0, source, + !source.isDirect(), null, null); + } + + /** + * Enqueue a command to write the given buffer from the given source Buffer. The size of the data transfer will be computed from the position and limit of the + * given Buffer. + * + * @param commandQueue The command queue + * @param buffer The target buffer + * @param targetOffset The offset (in number of elements) in the target buffer + * @param source The source Buffer + * @param blocking Whether the transfer should be blocking + * @param waitList The event wait list. May be null. + * @param event The event for this command. May be null. + */ + public static void enqueueWriteBuffer( + cl_command_queue commandQueue, + cl_mem buffer, + long targetOffset, + DoubleBuffer source, + boolean blocking, + List waitList, cl_event event) + { + Pointer sourcePointer = PointerUtils.toBuffer(source); + clEnqueueWriteBuffer(commandQueue, buffer, blocking, + targetOffset * Sizeof.cl_double, + source.remaining() * Sizeof.cl_double, sourcePointer, + sizeOf(waitList), asArray(waitList), event); + } + + + //======================================================================== + + + /** + * Returns the size of the given wait list, or 0 if it is null. + * + * @param waitList The wait list + * + * @return The size of the wait list + */ + private static int sizeOf(List waitList) + { + if(waitList == null) + { + return 0; + } + return waitList.size(); + } + + /** + * Returns the array representation of the given wait list, which is null if the given list is null or has length 0, or the elements + * of the given list otherwise. + * + * @param waitList The wait list + * + * @return The array for the given list + */ + private static cl_event[] asArray(List waitList) + { + if(waitList == null) + { + return null; + } + if(waitList.size() == 0) + { + return null; + } + return waitList.toArray(new cl_event[waitList.size()]); + } + + + /** + * Private constructor to prevent instantiation + */ + private CommandQueues() + { + } + +} diff --git a/src/main/java/org/jocl/utils/ContextInfos.java b/src/main/java/org/jocl/utils/ContextInfos.java new file mode 100644 index 0000000..e7883a1 --- /dev/null +++ b/src/main/java/org/jocl/utils/ContextInfos.java @@ -0,0 +1,137 @@ +/* + * JOCL Utilities + * + * Copyright (c) 2011-2012 Marco Hutter - http://www.jocl.org + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.jocl.utils; + +import org.jocl.Sizeof; +import org.jocl.cl_context; +import org.jocl.cl_device_id; + +import static org.jocl.CL.*; + +/** + * Utility methods for obtaining information about cl_context objects + */ +public class ContextInfos +{ + + /** + * The reference count. Only intended for identifying memory leaks. + * + * @param context The context + * + * @return The value + */ + public static int getReferenceCount(cl_context context) + { + return Infos.getInt(Infos.FOR_CONTEXT, context, + CL_CONTEXT_REFERENCE_COUNT); + } + + /** + * The number of devices associated with the context. + * + * @param context The context + * + * @return The value + */ + public static int getNumDevices(cl_context context) + { + return Infos.getInt(Infos.FOR_CONTEXT, context, + CL_CONTEXT_NUM_DEVICES); + } + + /** + * The devices associated with the context. + * + * @param context The context + * + * @return The value + */ + public static cl_device_id[] getDevices(cl_context context) + { + int numDevices = getNumDevices(context); + cl_device_id devices[] = new cl_device_id[numDevices]; + Infos.getPointers(Infos.FOR_CONTEXT, context, + CL_CONTEXT_DEVICES, devices); + cl_device_id nullDevice = new cl_device_id(); + for(int i = 0; i < numDevices; i++) + { + if(devices[i].equals(nullDevice)) + { + devices[i] = null; + } + } + return devices; + } + + /** + * The properties of the context. + * + * @param context The context + * + * @return The value + */ + public static long[] getProperties(cl_context context) + { + long valueSize = Infos.FOR_CONTEXT.getSize(context, + CL_CONTEXT_PROPERTIES); + int numValues = (int) (valueSize / Sizeof.POINTER); + return Infos.getSizes(Infos.FOR_CONTEXT, context, + CL_CONTEXT_PROPERTIES, numValues); + } + + /** + * The properties of the context, as Strings. The strings are the key-value pairs of the properties. The even indices of the properties array are assumed to + * be of type cl_context_properties, and the odd entries are assumed to be values that are returned in a hexadecimal form. + * + * @param context The context + * + * @return The value + */ + public static String[] getPropertiesStrings(cl_context context) + { + long properties[] = getProperties(context); + // Omit trailing '0' entry + String result[] = new String[properties.length - 1]; + for(int i = 0; i < properties.length / 2; i++) + { + long p0 = properties[i * 2 + 0]; + long p1 = properties[i * 2 + 1]; + result[i * 2 + 0] = stringFor_cl_context_properties((int) p0); + result[i * 2 + 1] = "0x" + Long.toHexString(p1); + } + return result; + } + + /** + * Private constructor to prevent instantiation + */ + private ContextInfos() + { + } +} diff --git a/src/main/java/org/jocl/utils/Contexts.java b/src/main/java/org/jocl/utils/Contexts.java new file mode 100644 index 0000000..5229f40 --- /dev/null +++ b/src/main/java/org/jocl/utils/Contexts.java @@ -0,0 +1,155 @@ +/* + * JOCL Utilities + * + * Copyright (c) 2011-2012 Marco Hutter - http://www.jocl.org + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.jocl.utils; + +import org.jocl.cl_context; +import org.jocl.cl_context_properties; +import org.jocl.cl_device_id; +import org.jocl.cl_platform_id; + +import java.util.Arrays; +import java.util.List; + +import static org.jocl.CL.*; + +/** + * Utility methods related to cl_context objects + */ +public class Contexts +{ + /** + * Create a new context for the given platform and devices. + * + * @param platform The platform + * @param devices The devices + * + * @return The new context + */ + public static cl_context create( + cl_platform_id platform, cl_device_id... devices) + { + return create(platform, Arrays.asList(devices), null); + } + + /** + * Create a new context for the given platform and devices. + * + * @param platform The platform + * @param devices The devices + * + * @return The new context + */ + public static cl_context create( + cl_platform_id platform, List devices) + { + return create(platform, devices, null); + } + + /** + * Create a new context with the given platform and devices, using the given additional context properties. The additional context properties are assumed to + * contain pairs of long values, where even entries contain the context property name, and odd values the corresponding value. This array may be + * null. + * + * @param platform The platform + * @param devices The devices + * @param additionalContextProperties Additional context properties + * + * @return The new context + */ + public static cl_context create( + cl_platform_id platform, List devices, + long additionalContextProperties[]) + { + cl_device_id devicesArray[] = + devices.toArray(new cl_device_id[devices.size()]); + + cl_context_properties contextProperties = new cl_context_properties(); + contextProperties.addProperty(CL_CONTEXT_PLATFORM, platform); + if(additionalContextProperties != null) + { + for(int i = 0; i < additionalContextProperties.length / 2; i++) + { + contextProperties.addProperty( + additionalContextProperties[i * 2 + 0], + additionalContextProperties[i * 2 + 1]); + } + } + cl_context context = clCreateContext( + contextProperties, devicesArray.length, + devicesArray, null, null, null); + return context; + } + + + /** + * Release each of the given contexts if it is not null. + * + * @param contexts The contexts to release + */ + public static void release(cl_context... contexts) + { + if(contexts != null) + { + for(cl_context context : contexts) + { + if(context != null) + { + clReleaseContext(context); + } + } + } + } + + /** + * Release each of the given contexts if it is not null. + * + * @param contexts The contexts to release + */ + public static void release(Iterable contexts) + { + if(contexts != null) + { + for(cl_context context : contexts) + { + if(context != null) + { + clReleaseContext(context); + } + } + } + } + + + /** + * Private constructor to prevent instantiation + */ + private Contexts() + { + } + +} diff --git a/src/main/java/org/jocl/utils/DeviceInfos.java b/src/main/java/org/jocl/utils/DeviceInfos.java new file mode 100644 index 0000000..f7f18c6 --- /dev/null +++ b/src/main/java/org/jocl/utils/DeviceInfos.java @@ -0,0 +1,884 @@ +/* + * JOCL Utilities + * + * Copyright (c) 2011-2012 Marco Hutter - http://www.jocl.org + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.jocl.utils; + +import org.jocl.cl_device_id; + +import static org.jocl.CL.*; + +/** + * Utility methods for obtaining information about cl_device_id objects + */ +public class DeviceInfos +{ + /** + * Device name string + * + * @param device The device + * + * @return The value + */ + public static String getName(cl_device_id device) + { + return Infos.getString(Infos.FOR_DEVICE, device, CL_DEVICE_NAME); + } + + /** + * Vendor name string + * + * @param device The device + * + * @return The value + */ + public static String getVendor(cl_device_id device) + { + return Infos.getString(Infos.FOR_DEVICE, device, + CL_DEVICE_VENDOR); + } + + /** + * A unique device vendor identifier + * + * @param device The device + * + * @return The value + */ + public static int getVendorId(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_VENDOR_ID); + } + + /** + * The OpenCL device type + * + * @param device The device + * + * @return The value + */ + public static long getType(cl_device_id device) + { + return Infos.getLong(Infos.FOR_DEVICE, device, + CL_DEVICE_TYPE); + } + + /** + * The OpenCL device type as a String + * + * @param device The device + * + * @return The value + */ + public static String getTypeString(cl_device_id device) + { + return stringFor_cl_device_type( + Infos.getLong(Infos.FOR_DEVICE, device, + CL_DEVICE_TYPE)); + } + + /** + * OpenCL version string + * + * @param device The device + * + * @return The value + */ + public static String getDeviceVersion(cl_device_id device) + { + return Infos.getString(Infos.FOR_DEVICE, device, + CL_DEVICE_VERSION); + } + + /** + * OpenCL software driver version string + * + * @param device The device + * + * @return The value + */ + public static String getDriverVersion(cl_device_id device) + { + return Infos.getString(Infos.FOR_DEVICE, device, + CL_DRIVER_VERSION); + } + + /** + * OpenCL profile string + * + * @param device The device + * + * @return The value + */ + public static String getProfile(cl_device_id device) + { + return Infos.getString(Infos.FOR_DEVICE, device, + CL_DEVICE_PROFILE); + } + + /** + * Maximum configured clock frequency in MHz + * + * @param device The device + * + * @return The value + */ + public static int getMaxClockFrequency(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_MAX_CLOCK_FREQUENCY); + } + + /** + * The number of parallel compute cores + * + * @param device The device + * + * @return The value + */ + public static int getMaxComputeUnits(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_MAX_COMPUTE_UNITS); + } + + /** + * Whether the device is available + * + * @param device The device + * + * @return The value + */ + public static boolean getAvailable(cl_device_id device) + { + return Infos.getBool(Infos.FOR_DEVICE, device, + CL_DEVICE_AVAILABLE); + } + + /** + * The default compute device address space size bits + * + * @param device The device + * + * @return The value + */ + public static int getAddressBits(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_ADDRESS_BITS); + } + + /** + * Whether the OpenCL device is a little endian device + * + * @param device The device + * + * @return The value + */ + public static boolean getEndianLittle(cl_device_id device) + { + return Infos.getBool(Infos.FOR_DEVICE, device, + CL_DEVICE_ENDIAN_LITTLE); + } + + /** + * Whether the implementation does have a compiler + * + * @param device The device + * + * @return The value + */ + public static boolean getCompilerAvailable(cl_device_id device) + { + return Infos.getBool(Infos.FOR_DEVICE, device, + CL_DEVICE_COMPILER_AVAILABLE); + } + + /** + * The highest OpenCL C version supported by the compiler + * + * @param device The device + * + * @return The value + */ + public static String getOpenclCVersion(cl_device_id device) + { + return Infos.getString(Infos.FOR_DEVICE, device, + CL_DEVICE_OPENCL_C_VERSION); + } + + /** + * Whether the device implements error correction + * + * @param device The device + * + * @return The value + */ + public static boolean getErrorCorrectionSupport(cl_device_id device) + { + return Infos.getBool(Infos.FOR_DEVICE, device, + CL_DEVICE_ERROR_CORRECTION_SUPPORT); + } + + /** + * Describes the execution capabilities of the device + * + * @param device The device + * + * @return The value + */ + public static long getExecutionCapabilities(cl_device_id device) + { + return Infos.getLong(Infos.FOR_DEVICE, device, + CL_DEVICE_EXECUTION_CAPABILITIES); + } + + /** + * Describes the execution capabilities of the device as a String + * + * @param device The device + * + * @return The value + */ + public static String getExecutionCapabilitiesString(cl_device_id device) + { + return stringFor_cl_device_exec_capabilities( + Infos.getLong(Infos.FOR_DEVICE, device, + CL_DEVICE_EXECUTION_CAPABILITIES)); + } + + /** + * A space-separated list of extension names + * + * @param device The device + * + * @return The value + */ + public static String getExtensions(cl_device_id device) + { + return Infos.getString(Infos.FOR_DEVICE, device, + CL_DEVICE_EXTENSIONS); + } + + /** + * Whether device and host have a unified memory subsystem + * + * @param device The device + * + * @return The value + */ + public static boolean getHostUnifiedMemory(cl_device_id device) + { + return Infos.getBool(Infos.FOR_DEVICE, device, + CL_DEVICE_HOST_UNIFIED_MEMORY); + } + + /** + * The resolution of device timer in nanoseconds + * + * @param device The device + * + * @return The value + */ + public static long getProfilingTimerResolution(cl_device_id device) + { + return Infos.getSize(Infos.FOR_DEVICE, device, + CL_DEVICE_PROFILING_TIMER_RESOLUTION); + } + + /** + * The supported command-queue properties + * + * @param device The device + * + * @return The value + */ + public static long getQueueProperties(cl_device_id device) + { + return Infos.getLong(Infos.FOR_DEVICE, device, + CL_DEVICE_QUEUE_PROPERTIES); + } + + /** + * The supported command-queue properties as a String + * + * @param device The device + * + * @return The value + */ + public static String getQueuePropertiesString(cl_device_id device) + { + return stringFor_cl_command_queue_properties( + Infos.getLong(Infos.FOR_DEVICE, device, + CL_DEVICE_QUEUE_PROPERTIES)); + } + + + /** + * Single precision floating-point capability + * + * @param device The device + * + * @return The value + */ + public static long getSingleFpConfig(cl_device_id device) + { + return Infos.getLong(Infos.FOR_DEVICE, device, + CL_DEVICE_SINGLE_FP_CONFIG); + } + + /** + * Single precision floating-point capability as a String + * + * @param device The device + * + * @return The value + */ + public static String getSingleFpConfigString(cl_device_id device) + { + return stringFor_cl_device_fp_config( + Infos.getLong(Infos.FOR_DEVICE, device, + CL_DEVICE_SINGLE_FP_CONFIG)); + } + + /** + * Size of global memory cache in bytes + * + * @param device The device + * + * @return The value + */ + public static long getGlobalMemCacheSize(cl_device_id device) + { + return Infos.getLong(Infos.FOR_DEVICE, device, + CL_DEVICE_GLOBAL_MEM_CACHE_SIZE); + } + + /** + * Type of global memory cache supported + * + * @param device The device + * + * @return The value + */ + public static long getGlobalMemCacheType(cl_device_id device) + { + return Infos.getLong(Infos.FOR_DEVICE, device, + CL_DEVICE_GLOBAL_MEM_CACHE_TYPE); + } + + /** + * Size of global memory cache line in bytes + * + * @param device The device + * + * @return The value + */ + public static int getGlobalMemCachelineSize(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE); + } + + /** + * Size of global device memory in bytes + * + * @param device The device + * + * @return The value + */ + public static long getGlobalMemSize(cl_device_id device) + { + return Infos.getLong(Infos.FOR_DEVICE, device, + CL_DEVICE_GLOBAL_MEM_SIZE); + } + + /** + * Whether images are supported by the OpenCL device + * + * @param device The device + * + * @return The value + */ + public static boolean getImageSupport(cl_device_id device) + { + return Infos.getBool(Infos.FOR_DEVICE, device, + CL_DEVICE_IMAGE_SUPPORT); + } + + /** + * Max height of 2D image in pixels + * + * @param device The device + * + * @return The value + */ + public static long getImage2dMaxHeight(cl_device_id device) + { + return Infos.getSize(Infos.FOR_DEVICE, device, + CL_DEVICE_IMAGE2D_MAX_HEIGHT); + } + + /** + * Max width of 2D image in pixels + * + * @param device The device + * + * @return The value + */ + public static long getImage2dMaxWidth(cl_device_id device) + { + return Infos.getSize(Infos.FOR_DEVICE, device, + CL_DEVICE_IMAGE2D_MAX_WIDTH); + } + + /** + * Max depth of 3D image in pixels + * + * @param device The device + * + * @return The value + */ + public static long getImage3dMaxDepth(cl_device_id device) + { + return Infos.getSize(Infos.FOR_DEVICE, device, + CL_DEVICE_IMAGE3D_MAX_DEPTH); + } + + /** + * Max height of 3D image in pixels + * + * @param device The device + * + * @return The value + */ + public static long getImage3dMaxHeight(cl_device_id device) + { + return Infos.getSize(Infos.FOR_DEVICE, device, + CL_DEVICE_IMAGE3D_MAX_HEIGHT); + } + + /** + * Max width of 3D image in pixels + * + * @param device The device + * + * @return The value + */ + public static long getImage3dMaxWidth(cl_device_id device) + { + return Infos.getSize(Infos.FOR_DEVICE, device, + CL_DEVICE_IMAGE3D_MAX_WIDTH); + } + + /** + * Size of local memory arena in bytes + * + * @param device The device + * + * @return The value + */ + public static long getLocalMemSize(cl_device_id device) + { + return Infos.getLong(Infos.FOR_DEVICE, device, + CL_DEVICE_LOCAL_MEM_SIZE); + } + + /** + * Type of local memory supported + * + * @param device The device + * + * @return The value + */ + public static long getLocalMemType(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_LOCAL_MEM_TYPE); + } + + /** + * Type of local memory supported as a String + * + * @param device The device + * + * @return The value + */ + public static String getLocalMemTypeString(cl_device_id device) + { + return stringFor_cl_device_local_mem_type( + Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_LOCAL_MEM_TYPE)); + } + + /** + * Max number of __constant kernel arguments + * + * @param device The device + * + * @return The value + */ + public static int getMaxConstantArgs(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_MAX_CONSTANT_ARGS); + } + + /** + * Max size in bytes of a constant buffer allocation + * + * @param device The device + * + * @return The value + */ + public static long getMaxConstantBufferSize(cl_device_id device) + { + return Infos.getLong(Infos.FOR_DEVICE, device, + CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE); + } + + /** + * Max size of memory object allocation in bytes + * + * @param device The device + * + * @return The value + */ + public static long getMaxMemAllocSize(cl_device_id device) + { + return Infos.getLong(Infos.FOR_DEVICE, device, + CL_DEVICE_MAX_MEM_ALLOC_SIZE); + } + + /** + * Max size in bytes of the kernel arguments + * + * @param device The device + * + * @return The value + */ + public static long getMaxParameterSize(cl_device_id device) + { + return Infos.getSize(Infos.FOR_DEVICE, device, + CL_DEVICE_MAX_PARAMETER_SIZE); + } + + /** + * Max number of simultaneous image objects that can be read by a kernel + * + * @param device The device + * + * @return The value + */ + public static int getMaxReadImageArgs(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_MAX_READ_IMAGE_ARGS); + } + + /** + * Maximum number of samplers that can be used in a kernel + * + * @param device The device + * + * @return The value + */ + public static int getMaxSamplers(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_MAX_SAMPLERS); + } + + /** + * Maximum number of work-items in a work-group + * + * @param device The device + * + * @return The value + */ + public static long getMaxWorkGroupSize(cl_device_id device) + { + return Infos.getSize(Infos.FOR_DEVICE, device, + CL_DEVICE_MAX_WORK_GROUP_SIZE); + } + + /** + * Maximum dimensions that specify the global and local work-item IDs + * + * @param device The device + * + * @return The value + */ + public static int getMaxWorkItemDimensions(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS); + } + + /** + * Maximum number of work-items for each dimension + * + * @param device The device + * + * @return The value + */ + public static long[] getMaxWorkItemSizes(cl_device_id device) + { + return Infos.getSizes(Infos.FOR_DEVICE, device, + CL_DEVICE_MAX_WORK_ITEM_SIZES, getMaxWorkItemDimensions(device)); + } + + /** + * Max number of simultaneous image objects that can be written to by a kernel + * + * @param device The device + * + * @return The value + */ + public static int getMaxWriteImageArgs(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_MAX_WRITE_IMAGE_ARGS); + } + + /** + * Describes the alignment in bits of memory objects + * + * @param device The device + * + * @return The value + */ + public static int getMemBaseAddrAlign(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_MEM_BASE_ADDR_ALIGN); + } + + /** + * The smallest alignment in bytes which can be used for any data type + * + * @param device The device + * + * @return The value + */ + public static int getMinDataTypeAlignSize(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE); + } + + /** + * Native ISA vector width (char) + * + * @param device The device + * + * @return The value + */ + public static int getNativeVectorWidthChar(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR); + } + + /** + * Native ISA vector width (short) + * + * @param device The device + * + * @return The value + */ + public static int getNativeVectorWidthShort(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT); + } + + /** + * Native ISA vector width (int) + * + * @param device The device + * + * @return The value + */ + public static int getNativeVectorWidthInt(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_NATIVE_VECTOR_WIDTH_INT); + } + + /** + * Native ISA vector width (long) + * + * @param device The device + * + * @return The value + */ + public static int getNativeVectorWidthLong(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG); + } + + /** + * Native ISA vector width (float) + * + * @param device The device + * + * @return The value + */ + public static int getNativeVectorWidthFloat(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT); + } + + /** + * Native ISA vector width (double) + * + * @param device The device + * + * @return The value + */ + public static int getNativeVectorWidthDouble(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE); + } + + /** + * Native ISA vector width (half) + * + * @param device The device + * + * @return The value + */ + public static int getNativeVectorWidthHalf(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF); + } + + /** + * Preferred native vector width (char) + * + * @param device The device + * + * @return The value + */ + public static int getPreferredVectorWidthChar(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR); + } + + /** + * Preferred native vector width (short) + * + * @param device The device + * + * @return The value + */ + public static int getPreferredVectorWidthShort(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT); + } + + /** + * Preferred native vector width (int) + * + * @param device The device + * + * @return The value + */ + public static int getPreferredVectorWidthInt(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT); + } + + /** + * Preferred native vector width (long) + * + * @param device The device + * + * @return The value + */ + public static int getPreferredVectorWidthLong(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG); + } + + /** + * Preferred native vector width (float) + * + * @param device The device + * + * @return The value + */ + public static int getPreferredVectorWidthFloat(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT); + } + + /** + * Preferred native vector width (double) + * + * @param device The device + * + * @return The value + */ + public static int getPreferredVectorWidthDouble(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE); + } + + /** + * Preferred native vector width (half) + * + * @param device The device + * + * @return The value + */ + public static int getPreferredVectorWidthHalf(cl_device_id device) + { + return Infos.getInt(Infos.FOR_DEVICE, device, + CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF); + } + + + /** + * Private constructor to prevent instantiation + */ + private DeviceInfos() + { + + } +} diff --git a/src/main/java/org/jocl/utils/Devices.java b/src/main/java/org/jocl/utils/Devices.java new file mode 100644 index 0000000..5fc4b71 --- /dev/null +++ b/src/main/java/org/jocl/utils/Devices.java @@ -0,0 +1,120 @@ +/* + * JOCL Utilities + * + * Copyright (c) 2011-2012 Marco Hutter - http://www.jocl.org + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +package org.jocl.utils; + +import org.jocl.CLException; +import org.jocl.cl_device_id; +import org.jocl.cl_platform_id; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.jocl.CL.*; + +/** + * Utility methods related to devices. + */ +public class Devices +{ + /** + * Returns an unmodifiable (possibly empty) list of all devices of the given platform. + * + * @param platform The platform + * + * @return The list of matching devices + */ + public static List getDevices(cl_platform_id platform) + { + return getDevices(platform, CL_DEVICE_TYPE_ALL); + } + + /** + * Returns an unmodifiable (possibly empty) list of all devices of the given platform that match the specified device type. The device type must be one of
CL_DEVICE_TYPE_CPU
CL_DEVICE_TYPE_GPU
CL_DEVICE_TYPE_ACCELERATOR
CL_DEVICE_TYPE_DEFAULT
CL_DEVICE_TYPE_ALL
+ * + * @param platform The platform + * @param deviceType The device type + * + * @return The list of matching devices + */ + public static List getDevices( + cl_platform_id platform, long deviceType) + { + // The clGetDeviceIDs method may cause an exception + // to be thrown when no matching devices are found. + // Return an empty list in this case. + int numDevicesArray[] = new int[1]; + try + { + int result = clGetDeviceIDs( + platform, deviceType, 0, null, numDevicesArray); + if(result == CL_DEVICE_NOT_FOUND) + { + return Collections.emptyList(); + } + } + catch(CLException e) + { + if(e.getStatus() == CL_DEVICE_NOT_FOUND) + { + return Collections.emptyList(); + } + throw e; + } + int numDevices = numDevicesArray[0]; + cl_device_id devices[] = new cl_device_id[numDevices]; + clGetDeviceIDs(platform, deviceType, numDevices, devices, null); + return Arrays.asList(devices); + } + + /** + * Private constructor to prevent instantiation + */ + private Devices() + { + } + + + @SuppressWarnings("unused") + private long maxFLOPs(cl_device_id device) + { + int maxComputeUnits = DeviceInfos.getMaxComputeUnits(device); + int maxClockFrequency = DeviceInfos.getMaxClockFrequency(device); + + //System.out.println("maxComputeUnits "+maxComputeUnits); + //System.out.println("maxClockFrequency "+maxClockFrequency); + + // TODO: The value '8' is only for NVIDIA cards!!! + long coresPerComputeUnit = 8; + long maxFlops = + maxComputeUnits * coresPerComputeUnit * + maxClockFrequency * 2 * 1000000; + return maxFlops; + } + +} diff --git a/src/main/java/org/jocl/utils/EventInfos.java b/src/main/java/org/jocl/utils/EventInfos.java new file mode 100644 index 0000000..02ff7e8 --- /dev/null +++ b/src/main/java/org/jocl/utils/EventInfos.java @@ -0,0 +1,150 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016 by luxe - https://github.com/de-luxe - BURST-LUXE-RED2-G6JW-H4HG5 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software + * is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies + * or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package org.jocl.utils; + +import org.jocl.cl_command_queue; +import org.jocl.cl_context; +import org.jocl.cl_event; + +import static org.jocl.CL.*; + +/** + * Utility methods for obtaining information about cl_event objects. + */ +public class EventInfos +{ + /** + * The command-queue associated with event + * + * @param event The event + * + * @return The value + */ + public static cl_command_queue getCommandQueue(cl_event event) + { + cl_command_queue result = new cl_command_queue(); + Infos.getPointer(Infos.FOR_EVENT, event, + CL_EVENT_COMMAND_QUEUE, result); + if(result.equals(new cl_command_queue())) + { + return null; + } + return result; + } + + /** + * The context that this event belongs to + * + * @param event The event + * + * @return The value + */ + public static cl_context getContext(cl_event event) + { + cl_context result = new cl_context(); + Infos.getPointer(Infos.FOR_EVENT, event, + CL_EVENT_CONTEXT, result); + if(result.equals(new cl_context())) + { + return null; + } + return result; + } + + /** + * The command associated with event + * + * @param event The event + * + * @return The value + */ + public static int getCommandType(cl_event event) + { + return Infos.getInt(Infos.FOR_EVENT, event, + CL_EVENT_COMMAND_TYPE); + } + + /** + * The command associated with event, as a String + * + * @param event The event + * + * @return The value + */ + public static String getCommandTypeString(cl_event event) + { + return stringFor_cl_command_type( + Infos.getInt(Infos.FOR_EVENT, event, + CL_EVENT_COMMAND_TYPE)); + } + + /** + * The execution status of the command identified by event. + * + * @param event The event + * + * @return The value + */ + public static int getCommandExecutionStatus(cl_event event) + { + return Infos.getInt(Infos.FOR_EVENT, event, + CL_EVENT_COMMAND_EXECUTION_STATUS); + + } + + /** + * The execution status of the command identified by event, as a String + * + * @param event The event + * + * @return The value + */ + public static String getCommandExecutionStatusString(cl_event event) + { + return stringFor_command_execution_status( + Infos.getInt(Infos.FOR_EVENT, event, + CL_EVENT_COMMAND_EXECUTION_STATUS)); + } + + + /** + * The reference count. Only intended for identifying memory leaks. + * + * @param event The event + * + * @return The value + */ + public static int getReferenceCount(cl_event event) + { + return Infos.getInt(Infos.FOR_EVENT, event, + CL_EVENT_REFERENCE_COUNT); + } + + + /** + * Private constructor to prevent instantiation + */ + private EventInfos() + { + } +} diff --git a/src/main/java/org/jocl/utils/EventProfilingInfos.java b/src/main/java/org/jocl/utils/EventProfilingInfos.java new file mode 100644 index 0000000..b590d72 --- /dev/null +++ b/src/main/java/org/jocl/utils/EventProfilingInfos.java @@ -0,0 +1,93 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016 by luxe - https://github.com/de-luxe - BURST-LUXE-RED2-G6JW-H4HG5 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software + * is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies + * or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package org.jocl.utils; + +import org.jocl.cl_event; + +import static org.jocl.CL.*; + +/** + * Utility methods for obtaining profiling information about cl_event objects. + */ +public class EventProfilingInfos +{ + /** + * The device counter, in nanoseconds, when the command of the given event was queued. + * + * @param event The event + * + * @return The value + */ + public static long getCommandQueued(cl_event event) + { + return Infos.getLong(Infos.FOR_EVENT_PROFILING, event, + CL_PROFILING_COMMAND_QUEUED); + } + + /** + * The device counter, in nanoseconds, when the command of the given event was submitted. + * + * @param event The event + * + * @return The value + */ + public static long getCommandSubmit(cl_event event) + { + return Infos.getLong(Infos.FOR_EVENT_PROFILING, event, + CL_PROFILING_COMMAND_SUBMIT); + } + + /** + * The device counter, in nanoseconds, when the command of the given event started execution. + * + * @param event The event + * + * @return The value + */ + public static long getCommandStart(cl_event event) + { + return Infos.getLong(Infos.FOR_EVENT_PROFILING, event, + CL_PROFILING_COMMAND_START); + } + + /** + * The device counter, in nanoseconds, when the command of the given event finished execution. + * + * @param event The event + * + * @return The value + */ + public static long getCommandEnd(cl_event event) + { + return Infos.getLong(Infos.FOR_EVENT_PROFILING, event, + CL_PROFILING_COMMAND_END); + } + + /** + * Private constructor to prevent instantiation + */ + private EventProfilingInfos() + { + + } +} diff --git a/src/main/java/org/jocl/utils/Events.java b/src/main/java/org/jocl/utils/Events.java new file mode 100644 index 0000000..43990ce --- /dev/null +++ b/src/main/java/org/jocl/utils/Events.java @@ -0,0 +1,137 @@ +/* + * JOCL Utilities + * + * Copyright (c) 2011-2012 Marco Hutter - http://www.jocl.org + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.jocl.utils; + +import org.jocl.cl_event; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.jocl.CL.*; + +/** + * Utility methods related to events. + */ +public class Events +{ + /** + * Compute the execution time for the given event, in milliseconds. This may only be called if the event is associated with a command queue for which + * profiling is enabled. + * + * @param event The event + * + * @return The execution time, in milliseconds + */ + public static double computeExecutionTimeMs(cl_event event) + { + long startTime = EventProfilingInfos.getCommandStart(event); + long endTime = EventProfilingInfos.getCommandEnd(event); + return (endTime - startTime) * 1e-6; + } + + + /** + * Wait for the given events if they are not null. + * + * @param events The events to wait for + */ + public static void waitFor(cl_event... events) + { + if(events != null) + { + waitFor(Arrays.asList(events)); + } + } + + /** + * Wait for the given events if they are not null. + * + * @param events The events to wait for + */ + public static void waitFor(Iterable events) + { + if(events != null) + { + List eventList = new ArrayList(); + for(cl_event event : events) + { + if(event != null) + { + eventList.add(event); + } + } + cl_event array[] = eventList.toArray( + new cl_event[eventList.size()]); + clWaitForEvents(array.length, array); + } + } + + + /** + * Release each of the given events if it is not null. + * + * @param events The events to release + */ + public static void release(cl_event... events) + { + if(events != null) + { + release(Arrays.asList(events)); + } + } + + /** + * Release each of the given events if it is not null. + * + * @param events The events to release + */ + public static void release(Iterable events) + { + if(events != null) + { + for(cl_event event : events) + { + if(event != null) + { + clReleaseEvent(event); + } + } + } + } + + + /** + * Private constructor to prevent instantiation + */ + private Events() + { + + } + +} diff --git a/src/main/java/org/jocl/utils/Infos.java b/src/main/java/org/jocl/utils/Infos.java new file mode 100644 index 0000000..451817a --- /dev/null +++ b/src/main/java/org/jocl/utils/Infos.java @@ -0,0 +1,493 @@ +/* + * JOCL Utilities + * + * Copyright (c) 2011-2012 Marco Hutter - http://www.jocl.org + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.jocl.utils; + +import org.jocl.NativePointerObject; +import org.jocl.Pointer; +import org.jocl.Sizeof; +import org.jocl.cl_command_queue; +import org.jocl.cl_context; +import org.jocl.cl_device_id; +import org.jocl.cl_event; +import org.jocl.cl_kernel; +import org.jocl.cl_mem; +import org.jocl.cl_platform_id; +import org.jocl.cl_program; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import static org.jocl.CL.*; + +/** + * Utility methods to obtain CL information + */ +class Infos +{ + /** + * Interface for methods to access CL information + * + * @param The type of the CL objects + */ + interface InfoGetter + { + /** + * Write the specified information for the given object into the given target + * + * @param object The object + * @param name The info name + * @param target The target + */ + void get(T object, int name, Pointer target); + + /** + * Returns the size of the specified information for the given object + * + * @param object The object + * @param name The info name + * + * @return The size + */ + long getSize(T object, int name); + } + + /** + * Implementation of an InfoGetter for devices + */ + static final InfoGetter FOR_DEVICE = + new InfoGetter() + { + private final long size[] = {0}; + + @Override + public long getSize(cl_device_id object, int name) + { + clGetDeviceInfo(object, name, 0, null, size); + return size[0]; + } + + @Override + public void get(cl_device_id object, int name, Pointer target) + { + long s = getSize(object, name); + clGetDeviceInfo(object, name, s, target, null); + } + }; + + /** + * Implementation of an InfoGetter for kernels + */ + static final InfoGetter FOR_KERNEL = + new InfoGetter() + { + private final long size[] = {0}; + + @Override + public long getSize(cl_kernel object, int name) + { + clGetKernelInfo(object, name, 0, null, size); + return size[0]; + } + + @Override + public void get(cl_kernel object, int name, Pointer target) + { + long s = getSize(object, name); + clGetKernelInfo(object, name, s, target, null); + } + }; + + /** + * Implementation of an InfoGetter for platforms + */ + static final InfoGetter FOR_PLATFORM = + new InfoGetter() + { + private final long size[] = {0}; + + @Override + public long getSize(cl_platform_id object, int name) + { + clGetPlatformInfo(object, name, 0, null, size); + return size[0]; + } + + @Override + public void get(cl_platform_id object, int name, Pointer target) + { + long s = getSize(object, name); + clGetPlatformInfo(object, name, s, target, null); + } + }; + + /** + * Implementation of an InfoGetter for mem objects + */ + static final InfoGetter FOR_MEM = + new InfoGetter() + { + private final long size[] = {0}; + + @Override + public long getSize(cl_mem object, int name) + { + clGetMemObjectInfo(object, name, 0, null, size); + return size[0]; + } + + @Override + public void get(cl_mem object, int name, Pointer target) + { + long s = getSize(object, name); + clGetMemObjectInfo(object, name, s, target, null); + } + }; + + + /** + * Implementation of an InfoGetter for event objects + */ + static final InfoGetter FOR_EVENT = + new InfoGetter() + { + private final long size[] = {0}; + + @Override + public long getSize(cl_event object, int name) + { + clGetEventInfo(object, name, 0, null, size); + return size[0]; + } + + @Override + public void get(cl_event object, int name, Pointer target) + { + long s = getSize(object, name); + clGetEventInfo(object, name, s, target, null); + } + }; + + /** + * Implementation of an InfoGetter for profiling of event objects + */ + static final InfoGetter FOR_EVENT_PROFILING = + new InfoGetter() + { + private final long size[] = {0}; + + @Override + public long getSize(cl_event object, int name) + { + clGetEventProfilingInfo(object, name, 0, null, size); + return size[0]; + } + + @Override + public void get(cl_event object, int name, Pointer target) + { + long s = getSize(object, name); + clGetEventProfilingInfo(object, name, s, target, null); + } + }; + + + /** + * Implementation of an InfoGetter for programs + */ + static final InfoGetter FOR_PROGRAM = + new InfoGetter() + { + private final long size[] = {0}; + + @Override + public long getSize(cl_program object, int name) + { + clGetProgramInfo(object, name, 0, null, size); + return size[0]; + } + + @Override + public void get(cl_program object, int name, Pointer target) + { + long s = getSize(object, name); + clGetProgramInfo(object, name, s, target, null); + } + }; + + /** + * Implementation of an InfoGetter for command queue objects + */ + static final InfoGetter FOR_COMMAND_QUEUE = + new InfoGetter() + { + private final long size[] = {0}; + + @Override + public long getSize(cl_command_queue object, int name) + { + clGetCommandQueueInfo(object, name, 0, null, size); + return size[0]; + } + + @Override + public void get(cl_command_queue object, int name, Pointer target) + { + long s = getSize(object, name); + clGetCommandQueueInfo(object, name, s, target, null); + } + }; + + + /** + * Implementation of an InfoGetter for context queue objects + */ + static final InfoGetter FOR_CONTEXT = + new InfoGetter() + { + private final long size[] = {0}; + + @Override + public long getSize(cl_context object, int name) + { + clGetContextInfo(object, name, 0, null, size); + return size[0]; + } + + @Override + public void get(cl_context object, int name, Pointer target) + { + long s = getSize(object, name); + clGetContextInfo(object, name, s, target, null); + } + }; + + + /** + * Returns the value of the info parameter with the given name + * + * @param infoGetter The info getter + * @param object The object + * @param paramName The parameter name + * @param The object type + * + * @return The value + */ + static boolean getBool( + InfoGetter infoGetter, T object, int paramName) + { + return getInts(infoGetter, object, paramName, 1)[0] != 0; + } + + /** + * Returns the value of the info parameter with the given name + * + * @param infoGetter The info getter + * @param object The object + * @param paramName The parameter name + * @param The object type + * + * @return The value + */ + static int getInt( + InfoGetter infoGetter, T object, int paramName) + { + return getInts(infoGetter, object, paramName, 1)[0]; + } + + /** + * Returns the values of the info parameter with the given name + * + * @param infoGetter The info getter + * @param object The object + * @param paramName The parameter name + * @param The object type + * @param numValues The number of values + * + * @return The values + */ + static int[] getInts( + InfoGetter infoGetter, T object, int paramName, int numValues) + { + int values[] = new int[numValues]; + infoGetter.get(object, paramName, Pointer.to(values)); + return values; + } + + /** + * Returns the value of the info parameter with the given name + * + * @param infoGetter The info getter + * @param object The object + * @param paramName The parameter name + * @param The object type + * + * @return The value + */ + static long getLong( + InfoGetter infoGetter, T object, int paramName) + { + return getLongs(infoGetter, object, paramName, 1)[0]; + } + + /** + * Returns the values of the info parameter with the given name + * + * @param infoGetter The info getter + * @param object The object + * @param paramName The parameter name + * @param The object type + * @param numValues The number of values + * + * @return The values + */ + static long[] getLongs( + InfoGetter infoGetter, T object, int paramName, int numValues) + { + long values[] = new long[numValues]; + infoGetter.get(object, paramName, Pointer.to(values)); + return values; + } + + /** + * Returns the value of the info parameter with the given name + * + * @param infoGetter The info getter + * @param object The object + * @param paramName The parameter name + * @param The object type + * + * @return The value + */ + static long getSize( + InfoGetter infoGetter, T object, int paramName) + { + return getSizes(infoGetter, object, paramName, 1)[0]; + } + + /** + * Returns the values of the info parameter with the given name + * + * @param infoGetter The info getter + * @param object The object + * @param paramName The parameter name + * @param The object type + * @param numValues The number of values + * + * @return The values + */ + static long[] getSizes( + InfoGetter infoGetter, T object, int paramName, int numValues) + { + ByteBuffer buffer = ByteBuffer.allocate( + numValues * Sizeof.size_t).order(ByteOrder.nativeOrder()); + infoGetter.get(object, paramName, Pointer.to(buffer)); + long values[] = new long[numValues]; + if(Sizeof.size_t == 4) + { + for(int i = 0; i < numValues; i++) + { + values[i] = buffer.getInt(i * Sizeof.size_t); + } + } + else + { + for(int i = 0; i < numValues; i++) + { + values[i] = buffer.getLong(i * Sizeof.size_t); + } + } + return values; + } + + /** + * Returns the value of the info parameter with the given name + * + * @param infoGetter The info getter + * @param object The object + * @param paramName The parameter name + * @param The object type + * + * @return The value + */ + static String getString( + InfoGetter infoGetter, T object, int paramName) + { + int size = (int) infoGetter.getSize(object, paramName); + byte buffer[] = new byte[size]; + infoGetter.get(object, paramName, Pointer.to(buffer)); + String result = new String(buffer, 0, buffer.length - 1); + return result.trim(); + } + + + /** + * Returns the value of the info parameter with the given name + * + * @param infoGetter The info getter + * @param object The object + * @param paramName The parameter name + * @param The object type + * @param The return type + * @param target The target + * + * @return The value + */ + static R getPointer( + InfoGetter infoGetter, T object, int paramName, R target) + { + infoGetter.get(object, paramName, Pointer.to(target)); + return target; + } + + /** + * Returns the value of the info parameter with the given name + * + * @param infoGetter The info getter + * @param object The object + * @param paramName The parameter name + * @param The object type + * @param The return type + * @param target The target + * + * @return The value + */ + static R[] getPointers( + InfoGetter infoGetter, T object, int paramName, R[] target) + { + infoGetter.get(object, paramName, Pointer.to(target)); + return target; + } + + /** + * Private constructor to prevent instantiation + */ + private Infos() + { + + } +} diff --git a/src/main/java/org/jocl/utils/KernelInfos.java b/src/main/java/org/jocl/utils/KernelInfos.java new file mode 100644 index 0000000..649769c --- /dev/null +++ b/src/main/java/org/jocl/utils/KernelInfos.java @@ -0,0 +1,121 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016 by luxe - https://github.com/de-luxe - BURST-LUXE-RED2-G6JW-H4HG5 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software + * is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies + * or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package org.jocl.utils; + +import org.jocl.cl_context; +import org.jocl.cl_kernel; +import org.jocl.cl_program; + +import static org.jocl.CL.*; + +/** + * Utility methods for obtaining information about cl_kernel objects + */ +public class KernelInfos +{ + /** + * The kernel function name. + * + * @param kernel The kernel + * + * @return The value + */ + public static String getFunctionName(cl_kernel kernel) + { + return Infos.getString(Infos.FOR_KERNEL, kernel, + CL_KERNEL_FUNCTION_NAME); + } + + /** + * The reference count - only provided for identifying memory leaks. + * + * @param kernel The kernel + * + * @return The value + */ + public static int getReferenceCount(cl_kernel kernel) + { + return Infos.getInt(Infos.FOR_KERNEL, kernel, + CL_KERNEL_REFERENCE_COUNT); + } + + /** + * The number of arguments + * + * @param kernel The kernel + * + * @return The value + */ + public static int getNumArgs(cl_kernel kernel) + { + return Infos.getInt(Infos.FOR_KERNEL, kernel, + CL_KERNEL_NUM_ARGS); + } + + /** + * The context that this kernel belongs to + * + * @param kernel The kernel + * + * @return The value + */ + public static cl_context getContext(cl_kernel kernel) + { + cl_context result = new cl_context(); + Infos.getPointer(Infos.FOR_KERNEL, kernel, + CL_KERNEL_CONTEXT, result); + if(result.equals(new cl_context())) + { + return null; + } + return result; + } + + /** + * The program that this kernel belongs to + * + * @param kernel The kernel + * + * @return The value + */ + public static cl_program getProgram(cl_kernel kernel) + { + cl_program result = new cl_program(); + Infos.getPointer(Infos.FOR_KERNEL, kernel, + CL_KERNEL_PROGRAM, result); + if(result.equals(new cl_program())) + { + return null; + } + return result; + } + + + /** + * Private constructor to prevent instantiation + */ + private KernelInfos() + { + } + +} diff --git a/src/main/java/org/jocl/utils/Kernels.java b/src/main/java/org/jocl/utils/Kernels.java new file mode 100644 index 0000000..30e5cc6 --- /dev/null +++ b/src/main/java/org/jocl/utils/Kernels.java @@ -0,0 +1,250 @@ +/* + * JOCL Utilities + * + * Copyright (c) 2011-2012 Marco Hutter - http://www.jocl.org + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.jocl.utils; + +import org.jocl.Pointer; +import org.jocl.Sizeof; +import org.jocl.cl_context; +import org.jocl.cl_kernel; +import org.jocl.cl_mem; +import org.jocl.cl_program; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; + +import static org.jocl.CL.*; + +/** + * Utility methods related to kernels and programs. + */ +public class Kernels +{ + /** + * The logger used in this class + */ +// private static final Logger logger = +// Logger.getLogger(Kernels.class.getName()); + + /** + * Creates an OpenCL kernel for the function with the given name in the given program. + * + * @param program The program + * @param kernelName The kernel name + * + * @return The program + */ + public static cl_kernel create( + cl_program program, String kernelName) + { + cl_kernel kernel = clCreateKernel(program, kernelName, null); + return kernel; + } + + /** + * Creates an OpenCL kernel for the function with the given name from the specified file. The program will be created using the given context, and released + * after the kernel has been created. + * + * @param context The context + * @param fileName The file name + * @param kernelName The name of the kernel + * @param compileOptions The compile options + * + * @return The kernel + * + * @throws IOException If the file can not be read + */ + public static cl_kernel createFromFile( + cl_context context, String fileName, String kernelName, + String... compileOptions) + throws IOException + { + cl_program program = Programs.createFromFile( + context, fileName, compileOptions); + cl_kernel kernel = create(program, kernelName); + clReleaseProgram(program); + return kernel; + } + + /** + * Creates an OpenCL program for the function with the given name from the given input stream. The program will be created using the given context, and + * released after the kernel has been created. The caller is responsible for closing the given stream after this method returns. + * + * @param context The context + * @param stream The stream + * @param kernelName The kernel name + * @param compileOptions The compile options + * + * @return The kernel + * + * @throws IOException If the stream can not be read + */ + public static cl_kernel createFromStream( + cl_context context, InputStream stream, String kernelName, + String... compileOptions) + throws IOException + { + cl_program program = Programs.createFromStream( + context, stream, compileOptions); + cl_kernel kernel = create(program, kernelName); + clReleaseProgram(program); + return kernel; + } + + /** + * Creates an OpenCL kernel for the function with the given name from the given source code. The program will be created using the given context, and released + * after the kernel has been created. + * + * @param context The context + * @param sourceCode The source code + * @param kernelName The kernel name + * @param compileOptions The compile options + * + * @return The kernel + */ + public static cl_kernel createFromSource( + cl_context context, String sourceCode, String kernelName, + String... compileOptions) + { + cl_program program = Programs.createFromSource( + context, sourceCode, compileOptions); + cl_kernel kernel = create(program, kernelName); + clReleaseProgram(program); + return kernel; + } + + /** + * Utility method to set the specified kernel arguments + * + * @param kernel The kernel + * @param args The arguments + * + * @throws IllegalArgumentException If the argument types are not primitive types and cl_mem + */ + public static void setArgs(cl_kernel kernel, Object... args) + { + for(int i = 0; i < args.length; i++) + { + Object arg = args[i]; + if(arg instanceof cl_mem) + { + cl_mem value = (cl_mem) arg; + Pointer pointer = Pointer.to(value); + clSetKernelArg(kernel, i, Sizeof.cl_mem, pointer); + //logger.info("argument "+i+" type is cl_mem"); + } + else if(arg instanceof Byte) + { + Byte value = (Byte) arg; + Pointer pointer = Pointer.to(new byte[]{value}); + clSetKernelArg(kernel, i, Sizeof.cl_char, pointer); + //logger.info("argument "+i+" type is Byte"); + } + else if(arg instanceof Short) + { + Short value = (Short) arg; + Pointer pointer = Pointer.to(new short[]{value}); + clSetKernelArg(kernel, i, Sizeof.cl_short, pointer); + //logger.info("argument "+i+" type is Short"); + } + else if(arg instanceof Integer) + { + Integer value = (Integer) arg; + Pointer pointer = Pointer.to(new int[]{value}); + clSetKernelArg(kernel, i, Sizeof.cl_int, pointer); + //logger.info("argument "+i+" type is Integer"); + } + else if(arg instanceof Long) + { + Long value = (Long) arg; + Pointer pointer = Pointer.to(new long[]{value}); + clSetKernelArg(kernel, i, Sizeof.cl_long, pointer); + //logger.info("argument "+i+" type is Long"); + } + else if(arg instanceof Float) + { + Float value = (Float) arg; + Pointer pointer = Pointer.to(new float[]{value}); + clSetKernelArg(kernel, i, Sizeof.cl_float, pointer); + //logger.info("argument "+i+" type is Float"); + } + else if(arg instanceof Double) + { + Double value = (Double) arg; + Pointer pointer = Pointer.to(new double[]{value}); + clSetKernelArg(kernel, i, Sizeof.cl_double, pointer); + //logger.info("argument "+i+" type is Double"); + } + else + { + throw new IllegalArgumentException( + "Type " + arg.getClass() + " may not be passed to a kernel"); + } + } + } + + /** + * Release each of the given kernels if it is not null. + * + * @param kernels The kernels to release + */ + public static void release(cl_kernel... kernels) + { + if(kernels != null) + { + release(Arrays.asList(kernels)); + } + } + + /** + * Release each of the given kernels if it is not null. + * + * @param kernels The kernels to release + */ + public static void release(Iterable kernels) + { + if(kernels != null) + { + for(cl_kernel kernel : kernels) + { + if(kernel != null) + { + clReleaseKernel(kernel); + } + } + } + } + + /** + * Private constructor to prevent instantiation + */ + private Kernels() + { + + } +} diff --git a/src/main/java/org/jocl/utils/MemInfos.java b/src/main/java/org/jocl/utils/MemInfos.java new file mode 100644 index 0000000..35aa96a --- /dev/null +++ b/src/main/java/org/jocl/utils/MemInfos.java @@ -0,0 +1,212 @@ +/* + * JOCL Utilities + * + * Copyright (c) 2011-2012 Marco Hutter - http://www.jocl.org + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.jocl.utils; + +import org.jocl.Pointer; +import org.jocl.cl_context; +import org.jocl.cl_mem; + +import static org.jocl.CL.*; + +/** + * Utility methods for obtaining information about cl_mem objects + */ +public class MemInfos +{ + /** + * The type of the memory object + * + * @param mem The mem + * + * @return The value + */ + public static int getType(cl_mem mem) + { + return Infos.getInt(Infos.FOR_MEM, mem, + CL_MEM_TYPE); + } + + /** + * The type of the memory object as a String + * + * @param mem The mem + * + * @return The value + */ + public static String getTypeString(cl_mem mem) + { + return stringFor_cl_mem_object_type( + Infos.getInt(Infos.FOR_MEM, mem, + CL_MEM_TYPE)); + } + + /** + * The flags specified when the memory object was created + * + * @param mem The mem + * + * @return The value + */ + public static long getFlags(cl_mem mem) + { + return Infos.getLong(Infos.FOR_MEM, mem, + CL_MEM_FLAGS); + } + + /** + * The flags specified when the memory object was created + * + * @param mem The mem + * + * @return The value + */ + public static String getFlagsString(cl_mem mem) + { + return stringFor_cl_mem_flags( + Infos.getLong(Infos.FOR_MEM, mem, + CL_MEM_FLAGS)); + } + + /** + * Size of the memory object in bytes + * + * @param mem The mem + * + * @return The value + */ + public static long getSize(cl_mem mem) + { + return Infos.getSize(Infos.FOR_MEM, mem, + CL_MEM_SIZE); + } + + /** + * The host pointer specified when the memory object was created. + * + * @param mem The mem + * + * @return The value + */ + public static Pointer getHostPtr(cl_mem mem) + { + Pointer result = new Pointer(); + Infos.getPointer(Infos.FOR_MEM, mem, + CL_MEM_HOST_PTR, result); + if(result.equals(new Pointer())) + { + return null; + } + return result; + } + + /** + * The map count - only provided for debugging. + * + * @param mem The mem + * + * @return The value + */ + public static int getMapCount(cl_mem mem) + { + return Infos.getInt(Infos.FOR_MEM, mem, + CL_MEM_MAP_COUNT); + } + + /** + * The reference count - only provided for identifying memory leaks. + * + * @param mem The mem + * + * @return The value + */ + public static int getReferenceCount(cl_mem mem) + { + return Infos.getInt(Infos.FOR_MEM, mem, + CL_MEM_REFERENCE_COUNT); + } + + /** + * The context that this memory object belongs to + * + * @param mem The mem + * + * @return The value + */ + public static cl_context getContext(cl_mem mem) + { + cl_context result = new cl_context(); + Infos.getPointer(Infos.FOR_MEM, mem, + CL_MEM_CONTEXT, result); + if(result.equals(new cl_context())) + { + return null; + } + return result; + } + + /** + * The memory object specified as buffer argument to clCreateSubBuffer, or NULL + * + * @param mem The mem + * + * @return The value + */ + public static cl_mem getAssociatedMemobject(cl_mem mem) + { + cl_mem result = new cl_mem(); + Infos.getPointer(Infos.FOR_MEM, mem, + CL_MEM_ASSOCIATED_MEMOBJECT, result); + if(result.equals(new cl_mem())) + { + return null; + } + return result; + } + + /** + * If the memory object is a sub-buffer, this is its offset, otherwise it is 0 + * + * @param mem The mem + * + * @return The value + */ + public static long getOffset(cl_mem mem) + { + return Infos.getSize(Infos.FOR_MEM, mem, + CL_MEM_OFFSET); + } + + + /** + * Private constructor to prevent instantiation + */ + private MemInfos() + { + + } +} diff --git a/src/main/java/org/jocl/utils/Mems.java b/src/main/java/org/jocl/utils/Mems.java new file mode 100644 index 0000000..6e1357a --- /dev/null +++ b/src/main/java/org/jocl/utils/Mems.java @@ -0,0 +1,209 @@ +/* + * JOCL Utilities + * + * Copyright (c) 2011-2012 Marco Hutter - http://www.jocl.org + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.jocl.utils; + +import org.jocl.Pointer; +import org.jocl.Sizeof; +import org.jocl.cl_context; +import org.jocl.cl_mem; + +import java.util.Arrays; + +import static org.jocl.CL.*; + +/** + * Utility methods related to memory objects. + */ +public class Mems +{ + + /** + * Create a memory object with the given size. + * + * @param context The context for which the memory object will be created + * @param size The size of the memory object, in bytes + * + * @return The memory object + */ + public static cl_mem create(cl_context context, int size) + { + cl_mem mem = clCreateBuffer( + context, CL_MEM_READ_WRITE, + size, null, null); + return mem; + } + + /** + * Create a memory object that contains the data from the given array + * + * @param context The context for which the memory object will be created + * @param array The array + * + * @return The memory object + */ + public static cl_mem create( + cl_context context, byte array[]) + { + return create( + context, array.length * Sizeof.cl_char, Pointer.to(array)); + } + + /** + * Create a memory object that contains the data from the given array + * + * @param context The context for which the memory object will be created + * @param array The array + * + * @return The memory object + */ + public static cl_mem create( + cl_context context, short array[]) + { + return create( + context, array.length * Sizeof.cl_short, Pointer.to(array)); + } + + /** + * Create a memory object that contains the data from the given array + * + * @param context The context for which the memory object will be created + * @param array The array + * + * @return The memory object + */ + public static cl_mem create( + cl_context context, int array[]) + { + return create( + context, array.length * Sizeof.cl_int, Pointer.to(array)); + } + + /** + * Create a memory object that contains the data from the given array + * + * @param context The context for which the memory object will be created + * @param array The array + * + * @return The memory object + */ + public static cl_mem create( + cl_context context, long array[]) + { + return create( + context, array.length * Sizeof.cl_long, Pointer.to(array)); + } + + /** + * Create a memory object that contains the data from the given array + * + * @param context The context for which the memory object will be created + * @param array The array + * + * @return The memory object + */ + public static cl_mem create( + cl_context context, float array[]) + { + return create( + context, array.length * Sizeof.cl_float, Pointer.to(array)); + } + + /** + * Create a memory object that contains the data from the given array + * + * @param context The context for which the memory object will be created + * @param array The array + * + * @return The memory object + */ + public static cl_mem create( + cl_context context, double array[]) + { + return create( + context, array.length * Sizeof.cl_double, Pointer.to(array)); + } + + /** + * Creates a memory object with the given size that contains the data from the given source pointer. + * + * @param context The context for which the memory object will be created + * @param size The size of the memory object, in bytes + * @param source The pointer to the source data + * + * @return The memory object + */ + private static cl_mem create( + cl_context context, long size, Pointer source) + { + cl_mem mem = clCreateBuffer( + context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, + size, source, null); + return mem; + } + + /** + * Release each of the given memory objects if it is not null. + * + * @param mems The memory objects to release + */ + public static void release(cl_mem... mems) + { + if(mems != null) + { + release(Arrays.asList(mems)); + } + } + + /** + * Release each of the given memory objects if it is not null. + * + * @param mems The memory objects to release + */ + public static void release(Iterable mems) + { + if(mems != null) + { + for(cl_mem mem : mems) + { + if(mem != null) + { + clReleaseMemObject(mem); + } + } + } + } + + + /** + * Private constructor to prevent instantiation + */ + private Mems() + { + + } +} diff --git a/src/main/java/org/jocl/utils/PlatformInfos.java b/src/main/java/org/jocl/utils/PlatformInfos.java new file mode 100644 index 0000000..8317ee1 --- /dev/null +++ b/src/main/java/org/jocl/utils/PlatformInfos.java @@ -0,0 +1,107 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016 by luxe - https://github.com/de-luxe - BURST-LUXE-RED2-G6JW-H4HG5 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software + * is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies + * or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package org.jocl.utils; + +import org.jocl.cl_platform_id; + +import static org.jocl.CL.*; + +/** + * Utility methods for obtaining information about cl_platform_id objects + */ +public class PlatformInfos +{ + /** + * Platform name string + * + * @param platform The platform + * + * @return The value + */ + public static String getName(cl_platform_id platform) + { + return Infos.getString(Infos.FOR_PLATFORM, platform, + CL_PLATFORM_NAME); + } + + /** + * Platform vendor string + * + * @param platform The platform + * + * @return The value + */ + public static String getVendor(cl_platform_id platform) + { + return Infos.getString(Infos.FOR_PLATFORM, platform, + CL_PLATFORM_VENDOR); + } + + /** + * OpenCL version string + * + * @param platform The platform + * + * @return The value + */ + public static String getVersion(cl_platform_id platform) + { + return Infos.getString(Infos.FOR_PLATFORM, platform, + CL_PLATFORM_VERSION); + } + + /** + * The profile name supported by the implementation + * + * @param platform The platform + * + * @return The value + */ + public static String getProfile(cl_platform_id platform) + { + return Infos.getString(Infos.FOR_PLATFORM, platform, + CL_PLATFORM_PROFILE); + } + + /** + * A space-separated list of extension names + * + * @param platform The platform + * + * @return The value + */ + public static String getExtensions(cl_platform_id platform) + { + return Infos.getString(Infos.FOR_PLATFORM, platform, + CL_PLATFORM_EXTENSIONS); + } + + + /** + * Private constructor to prevent instantiation + */ + private PlatformInfos() + { + } + +} diff --git a/src/main/java/org/jocl/utils/Platforms.java b/src/main/java/org/jocl/utils/Platforms.java new file mode 100644 index 0000000..f925c14 --- /dev/null +++ b/src/main/java/org/jocl/utils/Platforms.java @@ -0,0 +1,71 @@ +/* + * JOCL Utilities + * + * Copyright (c) 2011-2012 Marco Hutter - http://www.jocl.org + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.jocl.utils; + +import org.jocl.cl_platform_id; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.jocl.CL.*; + +/** + * Utility methods related to platforms. + */ +public class Platforms +{ + /** + * Returns an unmodifiable list of all available platforms + * + * @return The list of all available platforms + */ + public static List getPlatforms() + { + int numPlatformsArray[] = new int[1]; + clGetPlatformIDs(0, null, numPlatformsArray); + int numPlatforms = numPlatformsArray[0]; + + if(numPlatforms > 0) + { + cl_platform_id platforms[] = new cl_platform_id[numPlatforms]; + clGetPlatformIDs(platforms.length, platforms, null); + return Arrays.asList(platforms); + } + return Collections.emptyList(); + } + + + /** + * Private constructor to prevent instantiation + */ + private Platforms() + { + } + +} diff --git a/src/main/java/org/jocl/utils/PointerUtils.java b/src/main/java/org/jocl/utils/PointerUtils.java new file mode 100644 index 0000000..c73ef85 --- /dev/null +++ b/src/main/java/org/jocl/utils/PointerUtils.java @@ -0,0 +1,301 @@ +/* + * JOCL Utilities + * + * Copyright (c) 2011-2012 Marco Hutter - http://www.jocl.org + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.jocl.utils; + +import org.jocl.Pointer; +import org.jocl.Sizeof; + +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; + +/** + * Package-private class that offers the methods that are otherwise only available in JOCL > 0.1.7 + */ +class PointerUtils +{ + /** + * Creates a new Pointer to the given buffer, taking into account the array offset and position of the given buffer. + * + * @param buffer The buffer + * + * @return The new pointer + * + * @throws IllegalArgumentException If the given buffer is null or is neither direct nor has a backing array + */ + public static Pointer toBuffer(Buffer buffer) + { + if(buffer instanceof ByteBuffer) + { + return computePointer((ByteBuffer) buffer); + } + if(buffer instanceof ShortBuffer) + { + return computePointer((ShortBuffer) buffer); + } + if(buffer instanceof IntBuffer) + { + return computePointer((IntBuffer) buffer); + } + if(buffer instanceof LongBuffer) + { + return computePointer((LongBuffer) buffer); + } + if(buffer instanceof FloatBuffer) + { + return computePointer((FloatBuffer) buffer); + } + if(buffer instanceof DoubleBuffer) + { + return computePointer((DoubleBuffer) buffer); + } + throw new IllegalArgumentException( + "Unknown buffer type: " + buffer); + + } + + /** + * Creates a new Pointer to the given buffer, taking into account the position and array offset of the given buffer. + * + * @param buffer The buffer + * + * @return The pointer + * + * @throws IllegalArgumentException If the given buffer is null or is neither direct nor has a backing array + */ + private static Pointer computePointer(ByteBuffer buffer) + { + Pointer result = null; + if(buffer.isDirect()) + { + int oldPosition = buffer.position(); + buffer.position(0); + result = Pointer.to(buffer.slice()).withByteOffset( + oldPosition * Sizeof.cl_char); + buffer.position(oldPosition); + } + else if(buffer.hasArray()) + { + ByteBuffer t = ByteBuffer.wrap(buffer.array()); + int elementOffset = buffer.position() + buffer.arrayOffset(); + result = Pointer.to(t).withByteOffset( + elementOffset * Sizeof.cl_char); + } + else + { + throw new IllegalArgumentException( + "Buffer may not be null and must have an array or be direct"); + } + return result; + } + + + /** + * Creates a new Pointer to the given buffer, taking into account the position and array offset of the given buffer. + * + * @param buffer The buffer + * + * @return The pointer + * + * @throws IllegalArgumentException If the given buffer is null or is neither direct nor has a backing array + */ + private static Pointer computePointer(ShortBuffer buffer) + { + Pointer result = null; + if(buffer.isDirect()) + { + int oldPosition = buffer.position(); + buffer.position(0); + result = Pointer.to(buffer.slice()).withByteOffset( + oldPosition * Sizeof.cl_short); + buffer.position(oldPosition); + } + else if(buffer.hasArray()) + { + ShortBuffer t = ShortBuffer.wrap(buffer.array()); + int elementOffset = buffer.position() + buffer.arrayOffset(); + result = Pointer.to(t).withByteOffset( + elementOffset * Sizeof.cl_short); + } + else + { + throw new IllegalArgumentException( + "Buffer may not be null and must have an array or be direct"); + } + return result; + } + + + /** + * Creates a new Pointer to the given buffer, taking into account the position and array offset of the given buffer. + * + * @param buffer The buffer + * + * @return The pointer + * + * @throws IllegalArgumentException If the given buffer is null or is neither direct nor has a backing array + */ + private static Pointer computePointer(IntBuffer buffer) + { + Pointer result = null; + if(buffer.isDirect()) + { + int oldPosition = buffer.position(); + buffer.position(0); + result = Pointer.to(buffer.slice()).withByteOffset( + oldPosition * Sizeof.cl_int); + buffer.position(oldPosition); + } + else if(buffer.hasArray()) + { + IntBuffer t = IntBuffer.wrap(buffer.array()); + int elementOffset = buffer.position() + buffer.arrayOffset(); + result = Pointer.to(t).withByteOffset( + elementOffset * Sizeof.cl_int); + } + else + { + throw new IllegalArgumentException( + "Buffer may not be null and must have an array or be direct"); + } + return result; + } + + + /** + * Creates a new Pointer to the given buffer, taking into account the position and array offset of the given buffer. + * + * @param buffer The buffer + * + * @return The pointer + * + * @throws IllegalArgumentException If the given buffer is null or is neither direct nor has a backing array + */ + private static Pointer computePointer(LongBuffer buffer) + { + Pointer result = null; + if(buffer.isDirect()) + { + int oldPosition = buffer.position(); + buffer.position(0); + result = Pointer.to(buffer.slice()).withByteOffset( + oldPosition * Sizeof.cl_long); + buffer.position(oldPosition); + } + else if(buffer.hasArray()) + { + LongBuffer t = LongBuffer.wrap(buffer.array()); + int elementOffset = buffer.position() + buffer.arrayOffset(); + result = Pointer.to(t).withByteOffset( + elementOffset * Sizeof.cl_long); + } + else + { + throw new IllegalArgumentException( + "Buffer may not be null and must have an array or be direct"); + } + return result; + } + + + /** + * Creates a new Pointer to the given buffer, taking into account the position and array offset of the given buffer. + * + * @param buffer The buffer + * + * @return The pointer + * + * @throws IllegalArgumentException If the given buffer is null or is neither direct nor has a backing array + */ + private static Pointer computePointer(FloatBuffer buffer) + { + Pointer result = null; + if(buffer.isDirect()) + { + int oldPosition = buffer.position(); + buffer.position(0); + result = Pointer.to(buffer.slice()).withByteOffset( + oldPosition * Sizeof.cl_float); + buffer.position(oldPosition); + } + else if(buffer.hasArray()) + { + FloatBuffer t = FloatBuffer.wrap(buffer.array()); + int elementOffset = buffer.position() + buffer.arrayOffset(); + result = Pointer.to(t).withByteOffset( + elementOffset * Sizeof.cl_float); + } + else + { + throw new IllegalArgumentException( + "Buffer may not be null and must have an array or be direct"); + } + return result; + } + + + /** + * Creates a new Pointer to the given buffer, taking into account the position and array offset of the given buffer. + * + * @param buffer The buffer + * + * @return The pointer + * + * @throws IllegalArgumentException If the given buffer is null or is neither direct nor has a backing array + */ + private static Pointer computePointer(DoubleBuffer buffer) + { + Pointer result = null; + if(buffer.isDirect()) + { + int oldPosition = buffer.position(); + buffer.position(0); + result = Pointer.to(buffer.slice()).withByteOffset( + oldPosition * Sizeof.cl_double); + buffer.position(oldPosition); + } + else if(buffer.hasArray()) + { + DoubleBuffer t = DoubleBuffer.wrap(buffer.array()); + int elementOffset = buffer.position() + buffer.arrayOffset(); + result = Pointer.to(t).withByteOffset( + elementOffset * Sizeof.cl_double); + } + else + { + throw new IllegalArgumentException( + "Buffer may not be null and must have an array or be direct"); + } + return result; + } + +} diff --git a/src/main/java/org/jocl/utils/ProgramInfos.java b/src/main/java/org/jocl/utils/ProgramInfos.java new file mode 100644 index 0000000..eb67e13 --- /dev/null +++ b/src/main/java/org/jocl/utils/ProgramInfos.java @@ -0,0 +1,176 @@ +/* + * JOCL Utilities + * + * Copyright (c) 2011-2012 Marco Hutter - http://www.jocl.org + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.jocl.utils; + +import org.jocl.Pointer; +import org.jocl.cl_context; +import org.jocl.cl_device_id; +import org.jocl.cl_program; + +import static org.jocl.CL.*; + +/** + * Utility methods for obtaining information about cl_program objects + */ +public class ProgramInfos +{ + /** + * The reference count. Only intended for identifying memory leaks. + * + * @param program The program + * + * @return The value + */ + public static int getReferenceCount(cl_program program) + { + return Infos.getInt(Infos.FOR_PROGRAM, program, + CL_PROGRAM_REFERENCE_COUNT); + } + + /** + * The context of the program. + * + * @param program The program + * + * @return The value + */ + public static cl_context getContext(cl_program program) + { + cl_context result = new cl_context(); + Infos.getPointer(Infos.FOR_PROGRAM, program, + CL_PROGRAM_CONTEXT, result); + if(result.equals(new cl_context())) + { + return null; + } + return result; + } + + /** + * The number of devices associated with the program. + * + * @param program The program + * + * @return The value + */ + public static int getNumDevices(cl_program program) + { + return Infos.getInt(Infos.FOR_PROGRAM, program, + CL_PROGRAM_NUM_DEVICES); + } + + /** + * The devices associated with the program. + * + * @param program The program + * + * @return The value + */ + public static cl_device_id[] getDevices(cl_program program) + { + int numDevices = getNumDevices(program); + cl_device_id devices[] = new cl_device_id[numDevices]; + Infos.getPointers(Infos.FOR_PROGRAM, program, + CL_PROGRAM_DEVICES, devices); + cl_device_id nullDevice = new cl_device_id(); + for(int i = 0; i < numDevices; i++) + { + if(devices[i].equals(nullDevice)) + { + devices[i] = null; + } + } + return devices; + } + + /** + * The program source code + * + * @param program The program + * + * @return The value + */ + public static String getSource(cl_program program) + { + return Infos.getString(Infos.FOR_PROGRAM, program, + CL_PROGRAM_SOURCE); + } + + + /** + * The sizes of the program binaries for each device. + * + * @param program The program + * + * @return The value + */ + public static long[] getBinarySizes(cl_program program) + { + int numBinaries = getNumDevices(program); + return Infos.getSizes(Infos.FOR_PROGRAM, program, + CL_PROGRAM_BINARY_SIZES, numBinaries); + } + + /** + * The sizes of the program binaries for each device. + * + * @param program The program + * + * @return The value + */ + public static String[] getBinaries(cl_program program) + { + int numBinaries = getNumDevices(program); + long sizes[] = getBinarySizes(program); + byte dataArrays[][] = new byte[numBinaries][]; + Pointer dataPointers[] = new Pointer[numBinaries]; + for(int i = 0; i < numBinaries; i++) + { + dataArrays[i] = new byte[(int) sizes[i]]; + dataPointers[i] = Pointer.to(dataArrays[i]); + } + Infos.getPointers(Infos.FOR_PROGRAM, program, + CL_PROGRAM_BINARIES, dataPointers); + String dataStrings[] = new String[numBinaries]; + for(int i = 0; i < numBinaries; i++) + { + dataStrings[i] = new String(dataArrays[i], 0, (int) sizes[i] - 1); + } + return dataStrings; + } + + + /** + * Private constructor to prevent instantiation + */ + private ProgramInfos() + { + + } + +} diff --git a/src/main/java/org/jocl/utils/Programs.java b/src/main/java/org/jocl/utils/Programs.java new file mode 100644 index 0000000..a31af84 --- /dev/null +++ b/src/main/java/org/jocl/utils/Programs.java @@ -0,0 +1,242 @@ +/* + * JOCL Utilities + * + * Copyright (c) 2011-2012 Marco Hutter - http://www.jocl.org + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.jocl.utils; + +import org.jocl.Pointer; +import org.jocl.cl_context; +import org.jocl.cl_device_id; +import org.jocl.cl_program; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.logging.Logger; + +import static org.jocl.CL.*; + +/** + * Utility methods related to programs. + */ +public class Programs +{ + /** + * The logger used in this class + */ + private static final Logger logger = + Logger.getLogger(Programs.class.getName()); + + + /** + * Creates an OpenCL program for the function with the given name from the specified file. The program will be created using the given context, and has to be + * released by the caller, using {@link #release(cl_program...)}. + * + * @param context The context + * @param fileName The file name + * @param compileOptions The compile options + * + * @return The program + * + * @throws IOException If the file can not be read + */ + public static cl_program createFromFile( + cl_context context, String fileName, String... compileOptions) + throws IOException + { + String sourceCode = readFile(fileName); + return createFromSource(context, sourceCode); + } + + /** + * Creates an OpenCL program for the function with the given name from the given input stream. The program will be created using the given context, and has to + * be released by the caller, using {@link #release(cl_program...)} The caller is responsible for closing the given stream after this method returns. + * + * @param context The context + * @param stream The stream + * @param compileOptions The compile options + * + * @return The program + * + * @throws IOException If the stream can not be read + */ + public static cl_program createFromStream( + cl_context context, InputStream stream, String... compileOptions) + throws IOException + { + String sourceCode = readStream(stream); + return createFromSource(context, sourceCode); + } + + /** + * Creates an OpenCL program for the function with the given name from the given source code. The program will be created using the given context, and has to + * be released by the caller, using {@link #release(cl_program...)} + * + * @param context The context + * @param sourceCode The source code + * @param compileOptions The compile options + * + * @return The program + */ + public static cl_program createFromSource( + cl_context context, String sourceCode, String... compileOptions) + { + cl_program program = clCreateProgramWithSource(context, 1, + new String[]{sourceCode}, null, null); + + String compileOptionsString = null; + if(compileOptions != null) + { + StringBuilder sb = new StringBuilder(); + for(String compileOption : compileOptions) + { + sb.append(compileOption + " "); + } + compileOptionsString = sb.toString(); + } + clBuildProgram(program, 0, null, compileOptionsString, null, null); + return program; + } + + /** + * Returns the build logs for the given program as a string + * + * @param program The program + * + * @return The build logs + */ + public static String obtainBuildLogs(cl_program program) + { + cl_device_id devices[] = ProgramInfos.getDevices(program); + + StringBuffer sb = new StringBuffer(); + for(int i = 0; i < devices.length; i++) + { + sb.append("Build log for device " + i + ":\n"); + long logSize[] = new long[1]; + clGetProgramBuildInfo(program, devices[i], + CL_PROGRAM_BUILD_LOG, 0, null, logSize); + byte logData[] = new byte[(int) logSize[0]]; + clGetProgramBuildInfo(program, devices[i], + CL_PROGRAM_BUILD_LOG, logSize[0], Pointer.to(logData), null); + sb.append(new String(logData, 0, logData.length - 1)); + sb.append("\n"); + } + return sb.toString(); + } + + /** + * Read the contents of the file with the specified name and return it as a String. Returns null if an IO error occurs. + * + * @param fileName The file name + * + * @return The file contents as a string + * + * @throws IOException If the file can not be read + */ + private static String readFile(String fileName) + throws IOException + { + InputStream stream = null; + try + { + stream = new FileInputStream(fileName); + return readStream(stream); + } + finally + { + if(stream != null) + { + try + { + stream.close(); + } + catch(IOException e) + { + logger.warning("Could not close stream"); + } + } + } + } + + + /** + * Read the contents of the given stream and return it as a String. + * + * @param stream The stream + * + * @return The stream contents as a string + * + * @throws IOException If something goes wrong + */ + private static String readStream(InputStream stream) + throws IOException + { + BufferedReader br = new BufferedReader( + new InputStreamReader(stream)); + StringBuffer sb = new StringBuffer(); + String line = null; + while(true) + { + line = br.readLine(); + if(line == null) + { + break; + } + sb.append(line).append("\n"); + } + return sb.toString(); + } + + + /** + * Release each of the given programs if it is not null. + * + * @param programs The programs to release + */ + public static void release(cl_program... programs) + { + if(programs != null) + { + for(cl_program program : programs) + { + if(program != null) + { + clReleaseProgram(program); + } + } + } + } + + /** + * Private constructor to prevent instantiation + */ + private Programs() + { + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 1e8852c..62bd92a 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,4 +1,3 @@ -logging.level.burstcoin.jminer.core=INFO logging.level.org.eclipse.jetty.util.log=WARN logging.level.org.springframework=WARN -logging.file=jminer.logs.txt \ No newline at end of file +spring.jmx.enabled=false \ No newline at end of file diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt deleted file mode 100644 index e69de29..0000000