<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Bytedeco</title>
    <description>Bytedeco makes native libraries available to the Java platform by offering ready-to-use bindings generated with the codeveloped &lt;strong&gt;JavaCPP&lt;/strong&gt; technology. This, we hope, is the missing bridge between Java and C/C++, bringing compute-intensive science, multimedia, computer vision, deep learning, etc to the Java platform.</description>    
    <link>http://bytedeco.org</link>
    <atom:link href="http://bytedeco.org/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>Optimize and deploy models with JavaCPP and TVM</title>
        <description>&lt;p&gt;In the AI industry, the Java platform is used mainly when deploying to production. Consequently, it makes sense to provide easy access to all the tools and frameworks necessary to deploy deep learning models for Java. However, one of the most widely used frameworks, &lt;a href=&quot;https://tvm.apache.org/&quot;&gt;Apache TVM&lt;/a&gt;, did not have very good support for Java, until recently. With the &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/tvm&quot;&gt;JavaCPP Presets for TVM&lt;/a&gt;, we now have proper support for the Java platform.&lt;/p&gt;

&lt;p&gt;Still, according to the &lt;a href=&quot;https://github.com/apache/tvm&quot;&gt;GitHub repository of TVM&lt;/a&gt;, over 50% of the code is written in Python. This means that, for most use cases, we probably need to run some of those modules as part of the deployment pipeline. Moreover, there are usually preprocessing algorithms among other things that have been implemented only as Python scripts. For these reasons, we might as well make it easy as possible to execute this Python code from Java. This is where the &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/cpython&quot;&gt;JavaCPP Presets for CPython&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/llvm&quot;&gt;LLVM&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/mkl&quot;&gt;MKL&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/dnnl&quot;&gt;oneDNN (aka DNNL, MKL-DNN)&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/openblas&quot;&gt;OpenBLAS&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/numpy&quot;&gt;NumPy&lt;/a&gt;, and &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/scipy&quot;&gt;SciPy&lt;/a&gt; come in. They are available as normal JAR files, which can be used as any other JAR files, but they can also be used to satisfy the dependencies of TVM—without having to install anything! For example, as shown in the following sample project for OpenCV, we can bundle everything with &lt;a href=&quot;https://www.graalvm.org/reference-manual/native-image/&quot;&gt;GraalVM Native Image&lt;/a&gt; as usual and it simply just works as expected with &lt;a href=&quot;https://quarkus.io/&quot;&gt;Quarkus&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/bytedeco/sample-projects/tree/master/opencv-stitching-native&quot;&gt;https://github.com/bytedeco/sample-projects/tree/master/opencv-stitching-native&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;importing-and-optimizing-a-model&quot;&gt;Importing and optimizing a model&lt;/h3&gt;

&lt;p&gt;For the moment though, let us return to the focus of this post: Importing, optimizing, and deploying deep learning models with TVM in Java. One of the most recent and important breakthrough in the industry is the transformer architecture and models based on it such as BERT, for which TVM has been shown to deliver the highest performance, at least on CPU: &lt;a href=&quot;https://medium.com/apache-mxnet/speed-up-your-bert-inference-by-3x-on-cpus-using-apache-tvm-9cf7776cd7f8&quot;&gt;Speed up your BERT inference by 3x on CPUs using Apache TVM&lt;/a&gt;. We can embed, for example, the whole &lt;a href=&quot;https://gist.github.com/icemelon9/860d3d2c9566d6f69fa8112840dd95c1&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optimize_bert.py&lt;/code&gt; script&lt;/a&gt; as is in Java as demonstrated in this example, which also contains all the code found in this post:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/blob/master/tvm/samples/DeployBERT.java&quot;&gt;https://github.com/bytedeco/javacpp-presets/blob/master/tvm/samples/DeployBERT.java&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This script essentially imports a BERT model from GluonNLP and compares its performance with MXNet, but &lt;a href=&quot;https://tvm.apache.org/docs/tutorials/index.html#compile-deep-learning-models&quot;&gt;TVM also supports models in Keras, TensorFlow, ONNX, PyTorch, etc formats&lt;/a&gt;. In any case, to run that kind of script, we need to install all those Python packages first. This is where JavaCPP can help. With only these 3 lines of code, we are installing everything we need in JavaCPP’s cache, outside of any system or other user directories, so nothing gets broken, and the process is fully reproducible:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Extract to JavaCPP&apos;s cache CPython and obtain the path to the executable file&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;python&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Loader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bytedeco&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;cpython&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;python&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Install in JavaCPP&apos;s cache GluonNLP and MXNet to download and import BERT model&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ProcessBuilder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;python&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-m&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;pip&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;install&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;gluonnlp&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;mxnet&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;pytest&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;inheritIO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;waitFor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Add TVM and its dependencies to Python path using C API to embed script in Java&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Py_AddPath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bytedeco&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;tvm&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;presets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;tvm&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;cachePackages&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That makes it possible to execute the example successfully with a single Maven command and nothing more than a functional installation of the JDK, with everything getting downloaded, mainly from the Maven Central Repository and PyPI:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mvn clean compile &lt;span class=&quot;nb&quot;&gt;exec&lt;/span&gt;:java &lt;span class=&quot;nt&quot;&gt;-Djavacpp&lt;/span&gt;.platform.host &lt;span class=&quot;nt&quot;&gt;-Dexec&lt;/span&gt;.mainClass&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;DeployBERT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This outputs relevant information such as the following for an Intel(R) Xeon(R) Gold 6126 CPU @ 2.60GHz with 12 cores:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;MXNet latency for batch 1 and seq length 128: 57.88 ms
TVM latency for batch 1 and seq length 128: 22.45 ms
Running BERT runtime...
[ 0.06691778, 0.8569598 ]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;deploying-the-model&quot;&gt;&lt;br /&gt;Deploying the model&lt;/h3&gt;

&lt;p&gt;The above takes care of importing and optimizing models, but to achieve lower latency and/or higher throughput, we often need to perform inference without the additional overhead and restrictions of CPython. For this reason, after importing them, TVM can “export” models to native libraries. In this case, the DeployBERT example contains the following additional Python code to export the BERT model into a library named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libbert.so&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Export the model to a native library
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tvm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PassContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;opt_level&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;required_pass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;FastMath&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;compiled_lib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;relay&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;llvm -libs=mkl&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;compiled_lib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;export_library&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;lib/libbert.so&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once we have this native library, we are freed from the shackles of CPython. We can load and run inference on the model, where performance matters most, using only native code, plus (in our case) Java code based on the C/C++ API of the TVM runtime, which for our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libbert.so&lt;/code&gt; looks like this:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// load in the library&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;DLContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DLContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;device_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kDLCPU&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;device_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Module&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mod_factory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;LoadFromFile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;lib/libbert.so&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// create the BERT runtime module&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;TVMValue&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TVMValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;IntPointer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;codes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IntPointer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;TVMArgsSetter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TVMArgsSetter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;codes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;setter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;TVMRetValue&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rv&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TVMRetValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;mod_factory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;GetFunction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;CallPacked&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TVMArgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;codes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Module&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gmod&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;asModule&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;PackedFunc&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;set_input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gmod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;GetFunction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;set_input&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;PackedFunc&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gmod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;GetFunction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;get_output&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;PackedFunc&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gmod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;GetFunction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;run&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Use the C++ API to create some random sequence&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;DLDataType&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DLDataType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kDLFloat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bits&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;lanes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;short&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;NDArray&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NDArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Empty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;NDArray&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token_types&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NDArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Empty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;NDArray&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;valid_length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NDArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Empty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;NDArray&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NDArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Empty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;FloatPointer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputs_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FloatPointer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;accessDLTensor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;capacity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;FloatPointer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token_types_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FloatPointer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token_types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;accessDLTensor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;capacity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;FloatPointer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;valid_length_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FloatPointer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;valid_length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;accessDLTensor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;capacity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;FloatPointer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FloatPointer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;accessDLTensor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;capacity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;FloatIndexer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputs_idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FloatIndexer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs_data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;FloatIndexer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token_types_idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FloatIndexer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token_types_data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;FloatIndexer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;valid_length_idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FloatIndexer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;valid_length_data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;FloatIndexer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output_idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FloatIndexer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output_data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;Random&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;inputs_idx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;nextInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2000&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;token_types_idx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;nextFloat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;valid_length_idx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// set the right input&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;setter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BytePointer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;data0&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;setter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set_input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;CallPacked&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TVMArgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;codes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;setter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BytePointer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;data1&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;setter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token_types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set_input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;CallPacked&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TVMArgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;codes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;setter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BytePointer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;data2&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;setter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;valid_length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set_input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;CallPacked&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TVMArgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;codes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// run the code&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;CallPacked&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TVMArgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;codes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// get the output&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;setter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;setter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;get_output&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;CallPacked&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TVMArgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;codes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can of course implement a high-level API on top of all this to simplify the usage, as with the official Java API called &lt;a href=&quot;https://github.com/apache/tvm/tree/main/jvm&quot;&gt;TVM4J&lt;/a&gt;, which also comes bundled with the presets, so that works out of the box too, but it is quite limited and not always practical. Whichever API we use though, it should be clear that all the hard work can be done from the Java platform, in a portable and reproducible fashion, without having to install or build anything manually on the system.&lt;/p&gt;

&lt;p&gt;For CUDA on GPUs, we can also do something similar with the &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/tensorrt&quot;&gt;JavaCPP Presets for TensorRT&lt;/a&gt;, so be sure to check out this API as well along with the sample code written in Java:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/blob/master/tensorrt/samples/SampleGoogleNet.java&quot;&gt;https://github.com/bytedeco/javacpp-presets/blob/master/tensorrt/samples/SampleGoogleNet.java&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are having any issues with the code or would like to talk more about this subject, please feel free to communicate via the &lt;a href=&quot;http://groups.google.com/group/javacpp-project&quot;&gt;mailing list from Google Groups&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp/discussions&quot;&gt;discussions on GitHub&lt;/a&gt;, or &lt;a href=&quot;https://gitter.im/bytedeco/javacpp&quot;&gt;the chat room at Gitter&lt;/a&gt;. Happy New Year!&lt;/p&gt;
</description>
        <pubDate>Sat, 12 Dec 2020 00:00:00 +0000</pubDate>
        <link>http://bytedeco.org/news/2020/12/12/deploy-models-with-javacpp-and-tvm/</link>
        <guid isPermaLink="true">http://bytedeco.org/news/2020/12/12/deploy-models-with-javacpp-and-tvm/</guid>
      </item>
    
      <item>
        <title>Beyond Java and C++</title>
        <description>&lt;p&gt;We are happy to announce the first release of Bytedeco in this new Japanese era! Version 1.5 is available for &lt;a href=&quot;https://github.com/bytedeco/javacpp&quot;&gt;JavaCPP&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets&quot;&gt;JavaCPP Presets&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacv&quot;&gt;JavaCV&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/procamcalib&quot;&gt;ProCamCalib&lt;/a&gt;, and &lt;a href=&quot;https://github.com/bytedeco/procamtracker&quot;&gt;ProCamTracker&lt;/a&gt;. This release comes with new presets for NumPy (yes, the Python library, more on that below), NCCL, nGraph, Qt (providing an alternative to AWT, Swing, and JavaFX), and cpu_features, as well as updates for FFmpeg (now also including the &lt;a href=&quot;http://bytedeco.org/javacpp-presets/ffmpeg/apidocs/org/bytedeco/ffmpeg/ffmpeg.html&quot;&gt;ffmpeg&lt;/a&gt; and &lt;a href=&quot;http://bytedeco.org/javacpp-presets/ffmpeg/apidocs/org/bytedeco/ffmpeg/ffprobe.html&quot;&gt;ffprobe&lt;/a&gt; programs themselves), libfreenect, HDF5, MKL, MKL-DNN, LLVM, Leptonica, ARPACK-NG, CUDA, cuDNN, MXNet, TensorFlow, TensorRT, ONNX, LiquidFun, and Skia. Many thanks to all contributors! Since the &lt;a href=&quot;/news/2019/01/11/importance-of-a-distribution/&quot;&gt;previous post&lt;/a&gt; just 3 months ago, according to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git shortlog 1.4.4..1.5 --summary&lt;/code&gt;, they were:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Alex Merritt, Arnaud Jeansen, Greg Hart, HGuillemet, k3rnL, Samuel Audet, Simon Harris&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, as usual, this list does not contain anyone who very generously helped fix CI settings, test builds, debug code, file suggestions, make corrections, report bugs, propose ideas, update wiki pages, etc. One can find more detailed information about all these changes and fixes on the repositories listed above in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CHANGELOG.md&lt;/code&gt; files, among other places.&lt;/p&gt;

&lt;p&gt;As hinted previously though, the most important update concerns the modularization of all the artifacts to comply with the &lt;a href=&quot;https://en.wikipedia.org/wiki/Java_Platform_Module_System&quot;&gt;Java Platform Module System&lt;/a&gt; (JPMS). In theory, we simply have to add irritating &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;module-info.java&lt;/code&gt; files everywhere (we are grateful to &lt;a href=&quot;https://github.com/moditect/moditect&quot;&gt;ModiTect&lt;/a&gt; for the help with that), but one major restriction of JPMS is that we cannot split a Java package across multiple modules, so we had to update the packages of all the presets to comply, thus the minor version bump from 1.4.x to 1.5.x. In no small part thanks to Hervé Guillemet, we eventually managed to come up with a satisfactory naming scheme that not only complies with JPMS, but also produces top-level classes that are closer to typical Java APIs and that Javadoc can render more clearly into HTML. Instead of putting all classes in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;org.bytedeco.javacpp&lt;/code&gt; package, all modules now have their own packages based on the names of their artifacts, for example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;org.bytedeco.opencv&lt;/code&gt; in the case of OpenCV. Inside such a package we have top-level classes, further divided into subpackages when the artifact contains multiples native libraries, as well as a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;global&lt;/code&gt; subpackage containing, you guessed it, classes with native declarations for global C/C++ functions and variables. For most downstream projects, upgrading requires modifications to the import statements only. In the case of OpenCV and TensorFlow, for example, we would typically have statements like the following:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bytedeco&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;javacpp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;opencv_core&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.*;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bytedeco&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;javacpp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;opencv_imgproc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.*;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bytedeco&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;javacpp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;opencv_calib3d&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.*;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bytedeco&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;javacpp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;opencv_objdetect&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.*&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bytedeco&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;javacpp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;tensorflow&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.*;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Given these exact statements, to migrate to the new API, the only change required would be to replace them with the following:&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.bytedeco.opencv.opencv_core.*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.bytedeco.opencv.opencv_imgproc.*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.bytedeco.opencv.opencv_calib3d.*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.bytedeco.opencv.opencv_objdetect.*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.bytedeco.tensorflow.*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bytedeco&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;opencv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;opencv_core&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.*;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bytedeco&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;opencv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;opencv_imgproc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.*;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bytedeco&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;opencv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;opencv_calib3d&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.*;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bytedeco&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;opencv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;opencv_objdetect&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.*;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bytedeco&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;tensorflow&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;tensorflow&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.*;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To prevent conflicts with the old API, we also changed the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;groupId&lt;/code&gt; of all artifacts to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;org.bytedeco&lt;/code&gt;, so no more annoyingly long names containing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;org.bytedeco.javacpp-presets&lt;/code&gt;, which also reflects our evolving technical understanding of the world where the JVM cannot rule them all.&lt;/p&gt;

&lt;p&gt;Java is able to abstract away the underlying operating system, and, along with tools such as Maven and now &lt;a href=&quot;https://docs.oracle.com/javase/9/tools/jlink.htm&quot;&gt;jlink&lt;/a&gt; to create compact self-contained standalone applications as per the &lt;a href=&quot;https://github.com/bytedeco/sample-projects/tree/master/opencv-stitching-jlink&quot;&gt;opencv-stitching-jlink&lt;/a&gt; sample project, its abilities to manage the complexity of software in the ecosystem is unparalleled. However, the JVM itself is failing miserably at supporting other existing programming languages. We obviously need access to native libraries written in C/C++ for compute intensive algorithms, but even popular scripting languages such as JavaScript and Python have never been able to feel at home on the JVM either, notwithstanding their own arguably inferior native runtimes. &lt;a href=&quot;https://www.jython.org/&quot;&gt;Jython&lt;/a&gt; is stuck at Python 2.7, while &lt;a href=&quot;http://openjdk.java.net/jeps/335&quot;&gt;Nashorn has been deprecated&lt;/a&gt; even before its proposed successor, &lt;a href=&quot;https://github.com/graalvm/graaljs&quot;&gt;Graal JavaScript&lt;/a&gt;, is ready to take its place. Likewise, &lt;a href=&quot;https://github.com/graalvm/graalpython&quot;&gt;Graal Python&lt;/a&gt; is truly awesome technology, but is still an “early-stage experimental implementation” that runs pretty much nothing useful yet, let alone CUDA or any kind of support for GPU no where to be found on any roadmap. Whatever the cause is for the lack of the appearance of a universal VM that a majority of users would be happy with, it is instead possible to have multiple runtimes executing in the same process to share data efficiently, an approach that is also future-proof given that Graal still needs to implement JNI and the C API of Python anyway to be compatible with tools such as JNA, JNR, or JavaCPP, and libraries like NumPy or TensorFlow. We show that an initial implementation can be easily achieved today in the case of CPython and the current JDK, starting with the &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/numpy&quot;&gt;JavaCPP Presets for NumPy&lt;/a&gt;, which leaves all the high-level dependency management to Java and Maven, where JavaCPP automatically extracts the Python package to its cache, along with MKL on supported platforms, in a portable and repeatable fashion, without the need of any other less portable tools including Docker. In effect, this makes Python and NumPy available as a sort of domain-specific scripting language to Java developers. We plan on making more Python packages available this way, continuing next with the &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow&quot;&gt;JavaCPP Presets for TensorFlow&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you would like to participate in this effort, please communicate via the &lt;a href=&quot;http://groups.google.com/group/javacpp-project&quot;&gt;mailing list from Google Groups&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp/issues&quot;&gt;issues on GitHub&lt;/a&gt;, or &lt;a href=&quot;https://gitter.im/bytedeco/javacpp&quot;&gt;the chat room at Gitter&lt;/a&gt;. In any case, stay tuned for more exciting developments later this year!&lt;/p&gt;
</description>
        <pubDate>Thu, 11 Apr 2019 00:00:00 +0000</pubDate>
        <link>http://bytedeco.org/news/2019/04/11/beyond-java-and-cpp/</link>
        <guid isPermaLink="true">http://bytedeco.org/news/2019/04/11/beyond-java-and-cpp/</guid>
      </item>
    
      <item>
        <title>The importance of a distribution</title>
        <description>&lt;p&gt;Happy New Year! We were able to deliver yet another release on time. Version 1.4.4 is available for &lt;a href=&quot;https://github.com/bytedeco/javacpp&quot;&gt;JavaCPP&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets&quot;&gt;JavaCPP Presets&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacv&quot;&gt;JavaCV&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/procamcalib&quot;&gt;ProCamCalib&lt;/a&gt;, and &lt;a href=&quot;https://github.com/bytedeco/procamtracker&quot;&gt;ProCamTracker&lt;/a&gt;. Many thanks to all contributors! Since the &lt;a href=&quot;/news/2018/07/17/bytedeco-as-distribution/&quot;&gt;previous post&lt;/a&gt;, according to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git shortlog 1.4.2..1.4.4 --summary&lt;/code&gt;, they were:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Alex Merritt, Aman Gupta, Ao Qi, bitstormGER, deinhofer, Deividi, eguid, EmergentOrder, Gertjan Al, HGuillemet, Jarek Sacha, Jeremy Apthorp, kigkrazy, lloydmeta, louxiu, nahojjjen, Nico Hezel, renderdude, Samuel Audet, Taha Emara, vimalaguti, vincent-grosbois, wumo, Yuta Okamoto, Zayin Krige&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Many thanks as well to those not on this list but who helped fix CI settings, test builds, debug code, file suggestions, make corrections, report bugs, propose ideas, update wiki pages, etc. As usual this release fixes many issues and contains a lot of updates, all the details can be found in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CHANGELOG.md&lt;/code&gt; files, but one important change concerns MXNet, whose Scala API is now partially usable from Java. Consequently, the &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/mxnet&quot;&gt;JavaCPP Presets for MXNet&lt;/a&gt; now also bundle the official Scala API, just as with the official Java APIs of OpenCV and TensorFlow. Given these developments, there is one question that keeps coming up over and over again: Why do we need a distribution like Bytedeco even if everyone shows up with Java APIs on their own?&lt;/p&gt;

&lt;p&gt;Well, for one thing, the feature set exposed by these official APIs for Java is very limited, so many users still require access to the C/C++, Scala, or even Python APIs. Moreover, PyTorch is slated to become the first deep learning framework with &lt;a href=&quot;https://pytorch.org/cppdocs/&quot;&gt;a full-featured and easy-to-use C++ API&lt;/a&gt;, but with no plans in sight for Java, so once the C++ API becomes usable we intend on integrating it to Bytedeco as part of the JavaCPP Presets, see issue &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/issues/623&quot;&gt;bytedeco/javacpp-presets#623&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Another reason could be that JavaCPP provides a set of basic classes as foundation for native libraries, such as &lt;a href=&quot;http://bytedeco.org/javacpp/apidocs/org/bytedeco/javacpp/PointerScope.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PointerScope&lt;/code&gt;&lt;/a&gt; introduced in the &lt;a href=&quot;/news/2018/07/17/bytedeco-as-distribution/&quot;&gt;previous post&lt;/a&gt;. Thanks to Hervé Guillemet and Sam Carlberg, they will also soon support the Java Platfom Module System (JPMS), including &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jlink&lt;/code&gt;, something that the upstream projects have no plans to provide for their Java APIs. (A preview version of OpenCV is already available on the &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/jpms/opencv&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jpms&lt;/code&gt; branch&lt;/a&gt; with corresponding snapshot artifacts.) Although &lt;a href=&quot;http://openjdk.java.net/projects/panama/&quot;&gt;Project Panama&lt;/a&gt; promises to offer most of the features that &lt;a href=&quot;/faq/&quot;&gt;JavaCPP already provides today&lt;/a&gt;, delivery is expected only in a few more years, numbers showing faster-than-JNI performance for both JIT and AOT compilers are still lacking, development for C++ has yet to start, and it does not aspire to support platforms such as Android and iOS. Though, even in the case of plain Java SE, a loader for native libraries is required, something that community members such as &lt;a href=&quot;https://mail.openjdk.java.net/pipermail/workshop-discuss/2018-July/000007.html&quot;&gt;Johan Vos understand&lt;/a&gt;, but there are no plans to integrate such functionality to OpenJDK. Unless a fork like &lt;a href=&quot;https://github.com/corretto&quot;&gt;Corretto&lt;/a&gt; happens to stimulate evolution towards the demands of contemporary software development, I am afraid the need for a third-party tool like JavaCPP is here to stay for the foreseeable future.&lt;/p&gt;

&lt;p&gt;Nevertheless, assuming that Project Panama succeeds and renders JavaCPP obsolete—which would be awesome, although doubtful based on the discussion above, but just for the sake of the argument—the need for a distribution like Bytedeco will remain. The redistributable binaries for &lt;a href=&quot;https://developer.nvidia.com/cuda-downloads&quot;&gt;CUDA&lt;/a&gt; are over 2 GB for all supported platforms, compressed, and similarly for &lt;a href=&quot;https://software.intel.com/en-us/mkl&quot;&gt;MKL&lt;/a&gt;, which is about 0.5 GB for all supported platforms. These include aggressively optimized implementations of BLAS, LAPACK, and FFTW, among many other things, achieving at least 10× speedups over &lt;em&gt;anything&lt;/em&gt; one could possibly write in pure Java today. (Project Panama also promises to fix this for CPUs, eventually, but not for GPUs.) Their files are currently bundled by Bytedeco and shared by, for instance, &lt;a href=&quot;https://deeplearning4j.org/&quot;&gt;Deeplearning4j&lt;/a&gt;, and the &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets&quot;&gt;JavaCPP Presets for OpenCV, Caffe, MXNet, and TensorFlow&lt;/a&gt;. To offer a user-friendly experience, if each of these projects were to start bundling CUDA and MKL for all platforms on their own, an application depending on all those libraries may very well end up bundling over 10 GB of duplicate code! Projects competing against each other either downstream or upstream cannot offer such redistributables as shared resources: That is the role of a distribution. The goal is to make all those libraries, including the JDK itself, work well together.&lt;/p&gt;

&lt;p&gt;Right now, unless we are misinformed, Bytedeco is the only such distribution available for Java, however small it may be, which is indeed quite sad, but I hope this post helps spur more cooperation or, at the very least, some competition. There is still much to be done before the community at large begins to recognize the clear necessity for Java distributions of native libraries that work not only with Java SE on Linux, Mac, and Windows, but also for mobiles and embedded platforms such as Android, iOS, and Raspberry Pi.&lt;/p&gt;

&lt;p&gt;More concretely, to attain these goals, we will have to start putting more resources in priority into the following efforts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Obtain more visibility, gain a wider sense of community, by
    &lt;ul&gt;
      &lt;li&gt;Writing more blog posts, on a fancier web site,&lt;/li&gt;
      &lt;li&gt;Meeting people in person at conferences, workshops, etc, and&lt;/li&gt;
      &lt;li&gt;Participating in upstream projects, driving acceptance by their developers and users, by
        &lt;ul&gt;
          &lt;li&gt;Reporting bugs and helping to fix them, and even by&lt;/li&gt;
          &lt;li&gt;Contributing and maintaining JavaCPP-based wrappers upstream, among other things;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Aim for fully automated bindings generation for the features of C++ most widely used by native libraries,
    &lt;ul&gt;
      &lt;li&gt;In all probability with the help of &lt;a href=&quot;https://clang.llvm.org/docs/Tooling.html&quot;&gt;libclang&lt;/a&gt;, see issue &lt;a href=&quot;https://github.com/bytedeco/javacpp/issues/51&quot;&gt;bytedeco/javacpp#51&lt;/a&gt; and the &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/llvm/samples/&quot;&gt;samples in Java&lt;/a&gt;; and&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Keep &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/wiki/Create-New-Presets&quot;&gt;creating new presets&lt;/a&gt; for additional native libraries, &lt;em&gt;plus&lt;/em&gt; maintain them up-to-date with upstream projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A lot of help is going to be required to realize all this, so please spread the word! To contribute yourself to one of the items listed above, please communicate via the &lt;a href=&quot;http://groups.google.com/group/javacpp-project&quot;&gt;mailing list from Google Groups&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp/issues&quot;&gt;issues on GitHub&lt;/a&gt;, or &lt;a href=&quot;https://gitter.im/bytedeco/javacpp&quot;&gt;the chat room at Gitter&lt;/a&gt;. We are looking forward to continue working with everyone on all these projects this year as well!&lt;/p&gt;
</description>
        <pubDate>Fri, 11 Jan 2019 00:00:00 +0000</pubDate>
        <link>http://bytedeco.org/news/2019/01/11/importance-of-a-distribution/</link>
        <guid isPermaLink="true">http://bytedeco.org/news/2019/01/11/importance-of-a-distribution/</guid>
      </item>
    
      <item>
        <title>Bytedeco as a distribution</title>
        <description>&lt;p&gt;With version 1.4.2 now released, it’s time to publish a small blog post introducing the main innovations. As everyone probably knows, we’ve also released version 1.4.1 back in March. Thanks to the CI servers at &lt;a href=&quot;https://www.appveyor.com/&quot;&gt;AppVeyor&lt;/a&gt; and &lt;a href=&quot;https://www.travis-ci.org/&quot;&gt;Travis CI&lt;/a&gt;, we are now able to produce full releases of all binaries without too much effort, so we will probably be maintaining a release cycle of about 3 months. This brings Bytedeco one step closer to a distribution such as Anaconda, Fedora, or Ubuntu, but cross-platform and for multiple languages (that is being able to access native libraries from other languages than C++), where the presets for &lt;a href=&quot;https://opencv.org/&quot;&gt;OpenCV&lt;/a&gt; and &lt;a href=&quot;https://www.tensorflow.org/&quot;&gt;TensorFlow&lt;/a&gt;, for example, now also bundle the official Java APIs, but still provide users with access to the C/C++ APIs as well as additional features for better integration. &lt;a href=&quot;http://bytedeco.org/javacpp/apidocs/org/bytedeco/javacpp/PointerScope.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PointerScope&lt;/code&gt;&lt;/a&gt; is one such new feature that can help manage native memory, even when using multiple different APIs together.&lt;/p&gt;

&lt;p&gt;Until now, to prevent garbage from hanging around too long in memory, we had to call manually &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pointer.deallocate()&lt;/code&gt; on all native objects (either directly or with try-with-resources statements). We can now use a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PointerScope&lt;/code&gt; to manage a group of such objects, which is similar to &lt;a href=&quot;https://deeplearning4j.org/workspaces&quot;&gt;workspaces in Deeplearning4j&lt;/a&gt; (but without the workspace memory) or &lt;a href=&quot;http://cr.openjdk.java.net/~jrose/panama/panama-status-2015-1216.pdf&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scope&lt;/code&gt; from Panama&lt;/a&gt;, and as exemplified below for OpenCV and TensorFlow, a single &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PointerScope&lt;/code&gt; works even across libraries:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;checkStatus&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Status&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RuntimeException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;error_message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;detectObjects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;File&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Session&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// load the image file&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Mat&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;imread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getCanonicalPath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cvtColor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CV_BGR2RGB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Tensor&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Tensor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;DT_UINT8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TensorShape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;cols&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;channels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;mat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;arrayData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;capacity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;arraySize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()));&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// run inference&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputNames&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;image_tensor&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Tensor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputTensors&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outputNames&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;detection_boxes&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;detection_scores&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;detection_classes&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;num_detections&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;TensorVector&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outputTensors&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TensorVector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;checkStatus&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Run&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StringTensorPairVector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputNames&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputTensors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StringVector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;outputNames&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StringVector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outputTensors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// do something with outputTensors...&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// read the model&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;GraphDef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GraphDef&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;checkStatus&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReadBinaryProto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/path/to/frozen_inference_graph.pb&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// create the session&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Session&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SessionOptions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;checkStatus&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// detect objects from all files in directory&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;File&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/path/to/images/&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;File&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;listFiles&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;PointerScope&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PointerScope&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;detectObjects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Pointer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;physicalBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When executing this code with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opencv-platform&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tensorflow-platform&lt;/code&gt;, and the model file from &lt;a href=&quot;http://download.tensorflow.org/models/object_detection/ssd_inception_v2_coco_2017_11_17.tar.gz&quot;&gt;ssd_inception_v2_coco_2017_11_17.tar.gz&lt;/a&gt;, the output shows that memory usage rapidly stabilizes around 1 GB:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;955539456
1039908864
1065193472
1085517824
1087553536
1093492736
1139658752
1140494336
1141108736
1145044992
1145335808
1162153984
1163288576
1163067392
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;However, if we take the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PointerScope&lt;/code&gt; out of the loop, it goes on to fill up all the memory that we give it, which can easily exceed 16 GB by default on today’s machines:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;972619776
1058455552
1119633408
1162756096
1168207872
1189122048
1234366464
1306308608
1334439936
1362952192
1391730688
1421258752
1437138944
1493704704
1494519808
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is good not only to prevent wasting resources, but also to limit memory fragmentation. If you are interested in using TensorFlow this way, thanks to &lt;a href=&quot;https://github.com/neiko2002&quot;&gt;Nico Hezel&lt;/a&gt;, who also fixed the build for TensorFlow with CUDA support on Windows, additional samples are now available at:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow/samples&quot;&gt;https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow/samples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, other important changes include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;New artifacts for CUDA and cuDNN containing their redistributable libraries similarly to &lt;a href=&quot;https://hub.docker.com/r/nvidia/cuda/&quot;&gt;NVIDIA at Docker Hub&lt;/a&gt;, but that work also on Mac and Windows, to allow other libraries (Deeplearning4j, OpenCV, Caffe, TensorFlow, etc) to use GPUs without installing CUDA:
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/cuda&quot;&gt;https://github.com/bytedeco/javacpp-presets/tree/master/cuda&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;New presets for &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/arpack-ng&quot;&gt;ARPACK-NG&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/cminpack&quot;&gt;CMINPACK&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/tensorrt&quot;&gt;TensorRT&lt;/a&gt;, and &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/mkl-dnn&quot;&gt;MKL-DNN&lt;/a&gt; (which bundles a free version of MKL that other presets can use via &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/openblas&quot;&gt;OpenBLAS&lt;/a&gt;),&lt;/li&gt;
  &lt;li&gt;64-bit builds for Android (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;android-arm64&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;android-x86_64&lt;/code&gt;) and iOS (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ios-arm64&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ios-x86_64&lt;/code&gt;) that work with both &lt;a href=&quot;https://gluonhq.com/products/mobile/vm/&quot;&gt;Gluon VM&lt;/a&gt; and &lt;a href=&quot;http://robovm.mobidevelop.com/&quot;&gt;RoboVM&lt;/a&gt;,&lt;/li&gt;
  &lt;li&gt;New &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/LeptonicaFrameConverter.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LeptonicaFrameConverter&lt;/code&gt;&lt;/a&gt; for Tesseract and &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/JavaFXFrameConverter.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JavaFXFrameConverter&lt;/code&gt;&lt;/a&gt; for JavaFX (thanks to &lt;a href=&quot;https://github.com/johanvos&quot;&gt;Johan Vos&lt;/a&gt;), and&lt;/li&gt;
  &lt;li&gt;Support for audio frames in &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/FFmpegFrameFilter.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FFmpegFrameFilter&lt;/code&gt;&lt;/a&gt; bringing it on par with &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/FFmpegFrameGrabber.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FFmpegFrameGrabber&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/FFmpegFrameRecorder.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FFmpegFrameRecorder&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please find more information about these updates and other changes in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CHANGELOG.md&lt;/code&gt; files for &lt;a href=&quot;https://github.com/bytedeco/javacpp&quot;&gt;JavaCPP&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets&quot;&gt;JavaCPP Presets&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacv&quot;&gt;JavaCV&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/procamcalib&quot;&gt;ProCamCalib&lt;/a&gt;, and &lt;a href=&quot;https://github.com/bytedeco/procamtracker&quot;&gt;ProCamTracker&lt;/a&gt;. Many thanks to all contributors! According to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git shortlog 1.4..1.4.2 --summary&lt;/code&gt; they are:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;agiasmothi, Alex Black, Aman Gupta, canelzio, delthas, gunther82, Jeremy Apthorp, Jeremy Laviole, Johan Vos, Kevin Watters, louxiu, Mariano Scazzariello, Michael Haslgrübler, mifritscher, Nico Hezel, SIY1121, Sören Brunk, Stanislav Chizhik, Vincent Baines (vb216)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For completeness, here are all contributors since the beginning according to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git shortlog --summary&lt;/code&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Adam Gibson, agiasmothi, Agustin Alvarez, Alex Black, alicana, Aman Gupta, Amnon Owed, Amos Yuen, Andreas Eberle, Arseniy Pendryak, Ashley, beligum, Benjamin Hill, bennyveo, canelzio, Chetan Narsude, Chris Chow, Chris Nuernberger, Cyprien Noel (cypof), delthas, Djalma Antonio dos Passos Filho, Dmitriy Gerashenko, dragos-d, Edison Wang, Edu Garcia, egorapolonov, emilio1986, Fabrizio (Misto) Milo, Felix Andrews, Florian Enner, François Garillot, Fredrik Henricsson, Gabor Nagy, George Kankava, Gertjan Al, GroG (supertick), gunther82, HungHD, Jadon Fowler, Jarek Sacha (jarek), Jeremy Apthorp, Jeremy Laviole, Jeremy Martin, Jeroen Arens, jjYBdx4IL, Johan Vos, John Sichi, Jonathan Leitschuh, juergenuhl, kenji yoshida, Kevin Watters, leef, lfdversluis, Lloyd Chan (lloydmeta), louxiu, Luca Barbato, mabruce, Mariano Scazzariello, Martin, matrupihai, Maurice, Maurice Betzel (mbetzel), Michael Dietz, Michael Haslgrübler, Michael Tandy, Michal Conos, mifritscher, Miroslav Zoričák, mmanco, Mo Tao, mtandy, Nico Hezel, n-kai-cj, Oleg Kuliasov, Pachev Joseph, Paolo Bolettieri (paolobolettieri), Paul Gregoire, Paul Hammant, Paul Heideman, Pawel Hajduk, pchundi, Perry Nguyen, Philipp Moritz, Piotr, Richard Alam, Ryan Osial, Sam Carlberg, Samuel, Sean Carlisle, SIY1121, Sören Brunk, Stanislav Chizhik, Tatsuyuki Ishi, Teerapap Changwichukarn, The Gitter Badger, Tiago Daniel Jacobs, Tom Clark, Trejkaz (pen name), TwistedUmbrella, Vincent Baines (vb216), waldemarnt, Yizhi Liu, zhanhb, wmz7year, 李立强&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This list does not include anyone who has helped in other ways, including but not limited to fixing CI settings, testing builds, debugging code, filing issues, making corrections, reporting bugs, proposing ideas, updating the wiki, etc, but please do continue to communicate with us via the &lt;a href=&quot;http://groups.google.com/group/javacpp-project&quot;&gt;mailing list from Google Groups&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp/issues&quot;&gt;issues on GitHub&lt;/a&gt;, or &lt;a href=&quot;https://gitter.im/bytedeco/javacpp&quot;&gt;the chat room at Gitter&lt;/a&gt;. Your input is valuable, we hope to continue hearing from all of you!&lt;/p&gt;
</description>
        <pubDate>Tue, 17 Jul 2018 00:00:00 +0000</pubDate>
        <link>http://bytedeco.org/news/2018/07/17/bytedeco-as-distribution/</link>
        <guid isPermaLink="true">http://bytedeco.org/news/2018/07/17/bytedeco-as-distribution/</guid>
      </item>
    
      <item>
        <title>Java as a system programming language</title>
        <description>&lt;p&gt;Happy New Year! After spending over a year in (part-time) preparation for the next major release here at Bytedeco, version 1.4 has finally been released! A lot has been happening, so let me summarize the most important items. First, a million thanks to &lt;a href=&quot;https://github.com/vb216&quot;&gt;Vincent Baines&lt;/a&gt; for all the hard work getting builds to pass. We now have a proper continuous integration (CI) infrastructure based on &lt;a href=&quot;https://www.appveyor.com/&quot;&gt;AppVeyor&lt;/a&gt; and &lt;a href=&quot;https://www.travis-ci.org/&quot;&gt;Travis CI&lt;/a&gt; testing builds for pull requests as well as publishing SNAPSHOT artifacts for all platforms at each commit to the source code repositories. More information about that on the &lt;a href=&quot;/builds/&quot;&gt;builds page&lt;/a&gt;. Next, we have introduced the concept of “extension” to JavaCPP, letting us provide separate but optional CUDA builds for OpenCV, Caffe, and TensorFlow. To enable them, one simply needs to add to the class path the JAR files containing “-gpu” in their names, and JavaCPP will automatically pick them up based on their contents. On load error, it also gracefully fall backs on non-CUDA binaries. The list of currently available CUDA artifacts is given at the bottom of the &lt;a href=&quot;/download/&quot;&gt;download page&lt;/a&gt;. Finally, we have been busy closing the gap that prevents Java from being usable as a system programming language by introducing the &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/systems&quot;&gt;JavaCPP Presets for Systems&lt;/a&gt; to access system APIs such as libc and Win32.&lt;/p&gt;

&lt;p&gt;Before going into more details on the latter topic at hand, please find a complete list of all changes in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CHANGELOG.md&lt;/code&gt; files for &lt;a href=&quot;https://github.com/bytedeco/javacpp&quot;&gt;JavaCPP&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets&quot;&gt;JavaCPP Presets&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacv&quot;&gt;JavaCV&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/procamcalib&quot;&gt;ProCamCalib&lt;/a&gt;, and &lt;a href=&quot;https://github.com/bytedeco/procamtracker&quot;&gt;ProCamTracker&lt;/a&gt;. Binaries can be obtained as usual from the &lt;a href=&quot;http://search.maven.org/#search%7Cga%7C1%7Cbytedeco&quot;&gt;Maven Central Repository&lt;/a&gt;. New presets that were contributed include &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/libfreenect2&quot;&gt;libfreenect2&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/mkl&quot;&gt;MKL&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/libpostal&quot;&gt;libpostal&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/ale&quot;&gt;The Arcade Learning Environment (ALE)&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/liquidfun&quot;&gt;LiquidFun&lt;/a&gt;, and &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/skia&quot;&gt;Skia&lt;/a&gt;, in addition to the system APIs.&lt;/p&gt;

&lt;p&gt;Although Java is still the most widely used programming language, according to the &lt;a href=&quot;https://www.tiobe.com/tiobe-index/&quot;&gt;TIOBE Index&lt;/a&gt;, among many other sources, it is still not considered a system programming language and is conspicuously missing from the &lt;a href=&quot;https://en.wikipedia.org/wiki/System_programming_language#Major_languages&quot;&gt;list of system programming languages on Wikipedia&lt;/a&gt;. However, things are starting to change. Beginning with Java 9, the JDK supports &lt;a href=&quot;http://openjdk.java.net/jeps/295&quot;&gt;ahead-of-time (AOT) compilation of Java classes&lt;/a&gt;, something otherwise supported by &lt;a href=&quot;https://readytalk.github.io/avian/&quot;&gt;Avian&lt;/a&gt; and many others for a while already, thus allowing developers to create native executable programs that can be integrated into operating systems. Finally, thanks to JNI, JavaCPP, and now the systems presets, we can benefit easily from all the features (and suffer from all the pitfalls) of C++ right from the Java platform.&lt;/p&gt;

&lt;p&gt;Having access to systems APIs allows us to perform any operation supported by the underlying platform that is not otherwise mapped to a high-level Java API. Before the &lt;a href=&quot;http://openjdk.java.net/jeps/102&quot;&gt;process API updates&lt;/a&gt; included in Java 9, it was not possible to query all children and descendants of a process, or to kill forcibly an arbitrary process on the system, but it could still have been done with native APIs. However, it is still not possible, for example, to set the priority of a process on the system without resorting to external tools. With the systems presets, we can accomplish this with just a few lines of code, such as the following to set the current process priority to the lowest level, code that can also be executed interactively in a &lt;a href=&quot;https://docs.oracle.com/javase/9/jshell/introduction-jshell.htm&quot;&gt;JShell&lt;/a&gt; session:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.bytedeco.javacpp.*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;platform&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Loader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getPlatform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;linux&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;linux&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setpriority&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;linux&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;PRIO_PROCESS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;linux&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getpid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;macosx&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;macosx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setpriority&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;macosx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;PRIO_PROCESS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;macosx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getpid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;windows&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;windows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;SetPriorityClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;windows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;GetCurrentProcess&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;windows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;IDLE_PRIORITY_CLASS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can perform the same calls with other tools such as &lt;a href=&quot;https://github.com/java-native-access/jna&quot;&gt;JNA&lt;/a&gt; or &lt;a href=&quot;https://github.com/jnr&quot;&gt;JNR&lt;/a&gt;, but with JavaCPP we get a uniform layer that also supports C++ libraries, providing a level of integration as yet unmatched by any other solutions that we are aware of on any platform. In a nutshell, &lt;em&gt;any language&lt;/em&gt; targeting Java bytecode is now in a good position to become a system programming language, on the same level as the &lt;a href=&quot;https://golang.org/&quot;&gt;Go language&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;We hope that you are excited as we are in participating in this grand experiment, so please do not hesitate to contact us via the &lt;a href=&quot;http://groups.google.com/group/javacpp-project&quot;&gt;mailing list from Google Groups&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp/issues&quot;&gt;issues on GitHub&lt;/a&gt;, or &lt;a href=&quot;https://gitter.im/bytedeco/javacpp&quot;&gt;the chat room at Gitter&lt;/a&gt;, for any questions that you may have. We hope to hear from all of you soon!&lt;/p&gt;
</description>
        <pubDate>Wed, 17 Jan 2018 00:00:00 +0000</pubDate>
        <link>http://bytedeco.org/news/2018/01/17/java-for-systems/</link>
        <guid isPermaLink="true">http://bytedeco.org/news/2018/01/17/java-for-systems/</guid>
      </item>
    
      <item>
        <title>Refining native integration</title>
        <description>&lt;p&gt;Over the past few months, I have been busy integrating JavaCPP to &lt;a href=&quot;https://github.com/deeplearning4j/deeplearning4j&quot;&gt;Deeplearning4j&lt;/a&gt;, mainly as part of &lt;a href=&quot;https://github.com/deeplearning4j/nd4j&quot;&gt;ND4J&lt;/a&gt; and &lt;a href=&quot;https://github.com/deeplearning4j/datavec&quot;&gt;DataVec&lt;/a&gt;. Many bugs had to be fixed, we also needed to enhance native memory management, a few presets were created, but I actually spent most of my time trying to run &lt;a href=&quot;https://skymind.io/&quot;&gt;Skymind&lt;/a&gt; in Japan. In any case, thanks to all the team, Deeplearning4j has come a long way since last year, so if you have not given it a try recently, &lt;a href=&quot;https://deeplearning4j.org/&quot;&gt;make sure you do&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;However, a release at Bytedeco was long overdue, so I am proud to announce the availability of version 1.3! The source code and the binaries can be obtained as usual from GitHub and the Maven Central Repository for &lt;a href=&quot;https://github.com/bytedeco/javacpp&quot;&gt;JavaCPP&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets&quot;&gt;JavaCPP Presets&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacv&quot;&gt;JavaCV&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/procamcalib&quot;&gt;ProCamCalib&lt;/a&gt;, and &lt;a href=&quot;https://github.com/bytedeco/procamtracker&quot;&gt;ProCamTracker&lt;/a&gt;. This release comes with binaries for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;linux-armhf&lt;/code&gt; (for devices such as &lt;a href=&quot;https://www.raspberrypi.org/&quot;&gt;Raspberry Pi&lt;/a&gt;), thanks to Vince Baines for his continuous effort, as well as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;linux-ppc64le&lt;/code&gt;, built on &lt;a href=&quot;https://ny1.ptopenlab.com/dashboard/&quot;&gt;SuperVessel Cloud&lt;/a&gt;, which features virtual machines that IBM offers for free to the community. Lloyd Chan has also been maintaining &lt;a href=&quot;https://github.com/bytedeco/sbt-javacpp&quot;&gt;sbt-javacpp&lt;/a&gt; and &lt;a href=&quot;https://github.com/bytedeco/sbt-javacv&quot;&gt;sbt-javacv&lt;/a&gt;, while Andreas Eberle has generously provided &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow&quot;&gt;Android builds for TensorFlow&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To manage native memory more automatically, JavaCPP now monitors physical memory usage, also known as “resident set size” on Linux, Mac OS X, etc or “working set size” on Windows, as reported by the kernel. The maximum value defaults to 2 times &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Runtime.maxMemory()&lt;/code&gt;, which can be specified with the usual &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Xmx&lt;/code&gt; option on the command line, but we can also set it independently via the “org.bytedeco.javacpp.maxphysicalbytes” system property. When the whole process uses more physical memory than that amount, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;System.gc()&lt;/code&gt; followed by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Thread.sleep(100)&lt;/code&gt; are called a few times in a row, an amount adjustable via the “org.bytedeco.javacpp.maxretries” system property, in an attempt to free memory. With this strategy, we are able to tame memory usage more accurately no matter how it is being allocated.&lt;/p&gt;

&lt;p&gt;The presets that were created for this release are &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/librealsense&quot;&gt;librealsense&lt;/a&gt; (a great contribution from Jeremy Laviole), &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/hdf5&quot;&gt;HDF5&lt;/a&gt; (that Deeplearning4j uses to import models from Keras, Theano, and TensorFlow), and &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/openblas&quot;&gt;OpenBLAS&lt;/a&gt; (which also dynamically binds to MKL if found on the system or in the class path). Additions planned for the near future include &lt;a href=&quot;http://icl.cs.utk.edu/magma/software/&quot;&gt;MAGMA&lt;/a&gt; to supplement functionality missing from cuSOLVER. To simplify further the user experience, we also plan to offer bundles containing all the binaries for &lt;a href=&quot;https://developer.nvidia.com/cuda-downloads&quot;&gt;CUDA&lt;/a&gt; and &lt;a href=&quot;https://registrationcenter.intel.com/en/forms/?productid=2558&amp;amp;licensetype=2&quot;&gt;MKL&lt;/a&gt;, if it is determined that we are allowed to do so, which appears likely according to the EULAs that accompany their free downloads (&lt;a href=&quot;http://docs.nvidia.com/cuda/eula/index.html#attachment-a&quot;&gt;CUDA&lt;/a&gt; and
&lt;a href=&quot;https://software.intel.com/sites/default/files/managed/96/0a/Master_EULA_for_Intel_Sw_Development_Products.pdf&quot;&gt;MKL&lt;/a&gt;). Traditionally, we have to spend time either installing them manually or figuring out a way to automate the process on a case-by-case basis, using when possible platform-specific package managers or containers such as &lt;a href=&quot;https://www.docker.com/&quot;&gt;Docker&lt;/a&gt;, probably along with some scripts. Having such bundles available on the Maven Central Repository would relieve developers and operators from this burden.&lt;/p&gt;

&lt;p&gt;Other important changes include a &lt;a href=&quot;http://bytedeco.org/javacpp/apidocs/org/bytedeco/javacpp/indexer/HalfIndexer.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HalfIndexer&lt;/code&gt;&lt;/a&gt; to process in Java 16-bit half-precision floating-point data from CUDA or other libraries, the adoption of a user defined directory (defaults to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.javacpp/cache/&lt;/code&gt;) where JavaCPP now caches native library files, instead of extracting them into a temporary directory, and the introduction of “platform artifacts” for the JavaCPP Presets and JavaCV. Each entry in the cache is a directory with the same name as the JAR file from which the files are extracted, including the subdirectories, for example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opencv-3.1.0-1.3-linux-x86_64.jar/org/bytedeco/javacpp/linux-x86_64/libopencv_core.so.3.1&lt;/code&gt;. This way, the files are given a (most of the time) unique, predetermined, but easy to remember path, preventing not only the build up of messy temporary files, but also allowing for faster startup times as well as easier integration with native tools, outside the scope of JavaCPP. The technique also works for files other than libraries. Right now, the implementation does not support the extraction of whole directories, but when that becomes possible, one will be able to bundle header files, among other native resources, and have them available for immediate consumption with such a simple call as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Loader.cacheResource(opencv_core.class, &quot;include&quot;)&lt;/code&gt;. As a matter of course, the cache functions just as smoothly with uber JARs. “Platform artifacts” can also come in handy. Users are invited to add dependencies on those artifacts suffixed with “-platform”, for example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;javacv-platform&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opencv-platform&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ffmpeg-platform&lt;/code&gt;, etc, which in turn depend on binaries for all supported platforms. This new strategy was designed to work well with build systems other than Maven (sbt, Gradle, M2Eclipse, etc).&lt;/p&gt;

&lt;p&gt;On a final note, before long, we hope to have build servers running allowing us to make releases available in a more timely fashion. Stay tuned for updates, but in the meantime, do not hesitate to contact us through the &lt;a href=&quot;http://groups.google.com/group/javacpp-project&quot;&gt;mailing list from Google Groups&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp/issues&quot;&gt;issues on GitHub&lt;/a&gt;, or &lt;a href=&quot;https://gitter.im/bytedeco/javacpp&quot;&gt;the chat room at Gitter&lt;/a&gt;, for any questions that you may have. Contributions are also very welcome!&lt;/p&gt;
</description>
        <pubDate>Wed, 07 Dec 2016 00:00:00 +0000</pubDate>
        <link>http://bytedeco.org/news/2016/12/07/refining-native-integration/</link>
        <guid isPermaLink="true">http://bytedeco.org/news/2016/12/07/refining-native-integration/</guid>
      </item>
    
      <item>
        <title>Going deeper into deep learning</title>
        <description>&lt;p&gt;After more than half a year, we are finally making a release! You can obtain the new version 1.2 at the usual places on GitHub and the Maven Central Repository for &lt;a href=&quot;https://github.com/bytedeco/javacpp&quot;&gt;JavaCPP&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets&quot;&gt;JavaCPP Presets&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacv&quot;&gt;JavaCV&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/procamcalib&quot;&gt;ProCamCalib&lt;/a&gt;, and &lt;a href=&quot;https://github.com/bytedeco/procamtracker&quot;&gt;ProCamTracker&lt;/a&gt;. For Scala users, Lloyd Chan has also contributed &lt;a href=&quot;https://github.com/bytedeco/sbt-javacpp&quot;&gt;sbt-javacpp&lt;/a&gt; and &lt;a href=&quot;https://github.com/bytedeco/sbt-javacv&quot;&gt;sbt-javacv&lt;/a&gt;, offering them easy-to-use plugins for sbt. Thanks to Vince Baines, this release also contains a few binaries for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;linux-armhf&lt;/code&gt; platform, which work on most Raspberry Pi devices, among others. We also hope to have continuous integration (CI) set up before long to provide a larger selection of prebuilt binaries on all platforms for non-release versions as well.&lt;/p&gt;

&lt;p&gt;With regards to deep learning, we realized last year that JavaCPP had the characteristics of something that was in demand especially in that field, that is to say an easy way to access native libraries from an efficient platform like Java: &lt;a href=&quot;/news/2015/03/14/java-meets-caffe/&quot;&gt;Java meets Caffe, deep learning in perspective&lt;/a&gt;. Since then, Samuel has switched jobs and now works for &lt;a href=&quot;http://www.skymind.io/&quot;&gt;Skymind&lt;/a&gt;, integrating &lt;a href=&quot;https://github.com/bytedeco/javacpp&quot;&gt;JavaCPP&lt;/a&gt;, the &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets&quot;&gt;JavaCPP Presets&lt;/a&gt;, and &lt;a href=&quot;https://github.com/bytedeco/javacv&quot;&gt;JavaCV&lt;/a&gt; into &lt;a href=&quot;https://github.com/deeplearning4j/nd4j&quot;&gt;ND4J&lt;/a&gt; and &lt;a href=&quot;https://github.com/deeplearning4j/deeplearning4j&quot;&gt;Deeplearning4j&lt;/a&gt;, as well as pursuing other avenues, such as maintaining not only &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/caffe&quot;&gt;bindings for Caffe&lt;/a&gt; and &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/cuda&quot;&gt;cuDNN&lt;/a&gt;, but also for &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/mxnet&quot;&gt;MXNet&lt;/a&gt; and &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow&quot;&gt;TensorFlow&lt;/a&gt;, among others. Many thanks to Adam Gibson and Chris Nicholson for their trust! I am sure we will achieve great things together.&lt;/p&gt;

&lt;p&gt;That said, to attain accuracies higher than traditional methods, deep learning requires a lot of data. That makes it a good candidate for data processing in big data applications. Naturally, they consume large amounts of memory, but Java cannot access arrays larger that can be indexed with a 32-bit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; variable. This is an inherit limitation of the JVM. Given that Hadoop on Java is the de facto standard when it comes to big data applications, it makes sense to have a solution to that limitation. To support 64-bit indexing, we have thus extended the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;position&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;limit&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;capacity&lt;/code&gt; fields of the &lt;a href=&quot;http://bytedeco.org/javacpp/apidocs/org/bytedeco/javacpp/Pointer.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pointer&lt;/code&gt;&lt;/a&gt; class to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;long&lt;/code&gt;. Moreover, since standard NIO buffers do not support &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;long&lt;/code&gt; indexing, we provide a new backend for the &lt;a href=&quot;http://bytedeco.org/javacpp/apidocs/org/bytedeco/javacpp/indexer/package-summary.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;indexer&lt;/code&gt;&lt;/a&gt; package using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sun.misc.Unsafe&lt;/code&gt;. Indexing memory with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;long&lt;/code&gt; variables represents a fundamental shift in the API, so it might break some existing code, but nothing too dramatic, we hope. On the brighter side, performance on 64-bit architectures is not affected.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://bytedeco.org/javacpp/apidocs/org/bytedeco/javacpp/indexer/Indexer.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Indexer&lt;/code&gt;&lt;/a&gt; also now implements &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AutoCloseable&lt;/code&gt;, to obtain the same benefit as with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pointer&lt;/code&gt; and try-with-resources constructs. For applications that cannot take advantage of this for memory management purposes, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pointer&lt;/code&gt; now also tracks the amount of memory allocated as reported by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;capacity&lt;/code&gt; field. This does not work for most native libraries, more work would be required to query memory consumption from the operating system, but it works when allocating arrays of simple types with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;allocateArray()&lt;/code&gt;. Once memory consumption tracked this way reaches &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pointer.maxBytes&lt;/code&gt;, the allocator will do its best to reclaim memory by calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;System.gc()&lt;/code&gt;, waiting a bit, and retrying a few times in a loop.&lt;/p&gt;

&lt;p&gt;That about covers the essential changes in this release, but other things have been fixed and updated too, so we invite you to check the changelogs and to contact us through the &lt;a href=&quot;http://groups.google.com/group/javacpp-project&quot;&gt;mailing list from Google Groups&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp/issues&quot;&gt;issues on GitHub&lt;/a&gt;, or &lt;a href=&quot;https://gitter.im/bytedeco/javacpp&quot;&gt;the chat room at Gitter&lt;/a&gt;, for any questions that you may have. Together, let’s make the future happen!&lt;/p&gt;
</description>
        <pubDate>Sun, 15 May 2016 00:00:00 +0000</pubDate>
        <link>http://bytedeco.org/news/2016/05/15/deeper-in-deep-learning/</link>
        <guid isPermaLink="true">http://bytedeco.org/news/2016/05/15/deeper-in-deep-learning/</guid>
      </item>
    
      <item>
        <title>Moving to Java SE 7</title>
        <description>&lt;p&gt;A few months have already passed since the last release, encouraging us to create a new one, which we have just done! Version 1.1 of &lt;a href=&quot;https://github.com/bytedeco/javacpp&quot;&gt;JavaCPP&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets&quot;&gt;JavaCPP Presets&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacv&quot;&gt;JavaCV&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/procamcalib&quot;&gt;ProCamCalib&lt;/a&gt;, and &lt;a href=&quot;https://github.com/bytedeco/procamtracker&quot;&gt;ProCamTracker&lt;/a&gt; are now available, and they depend on Java SE 7. We felt that since everyone is now comfortable with Java SE 8, it was time to drop compatibility with Java SE 6. :) Seriously, the main reason behind the change was to provide support for the &lt;a href=&quot;https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html&quot;&gt;try-with-resources construct&lt;/a&gt;, instead of relying solely on the garbage collector to imitate C++-like memory management semantics, aka “Resource Acquisition Is Initialization (RAII)”. This required making the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pointer&lt;/code&gt; class implement the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AutoCloseable&lt;/code&gt; interface, a tiny but important interface. Many thanks to Adam Gibson and Cyprien Noel for having successfully convinced me to make this change. Android also provides that interface since version 4.0, covering more than 95% of all Android users at the time of this writing, according to &lt;a href=&quot;http://developer.android.com/about/dashboards/&quot;&gt;Android Dashboards&lt;/a&gt;. So, the choice was not so hard to make after all, and JavaCPP now requires Android 4.0.&lt;/p&gt;

&lt;p&gt;That said, what does try-with-resources gets us anyway? It provides a user-friendly way to release resources in a deterministic manner, something that a lot of C++ libraries take for granted. There is no guarantees that the garbage collector will ever run. It only cares about memory allocated on the Java heap, and if we allocate chunks of memory only from the native heap, it might decide to never run, a situation that can easily become problematic. Also, we cannot predict on which thread memory eventually gets deallocated. We cannot force any given thread used for an allocation to come back at some point for deallocation: It might disappear at any time without any warning. The point is, for more than a few reasons, people came up with this concept to provide services garbage collection was unable to provide. As a concrete example, in the traditional paradigm, there are occasions when we would write the following:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;nc&quot;&gt;MyPointer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyPointer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// use data...&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;finally&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;deallocate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With try-with-resources, we can rewrite the logic above into a single statement like this:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MyPointer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyPointer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// use data ...&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A lot cleaner, and thus a lot less error-prone. Exceptions also behave better, but that is about the gist of it. By the way, this also works with native smart pointers such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;boost::shared_ptr&lt;/code&gt; (Boost), &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;std::shared_ptr&lt;/code&gt; (C++11), &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cv::Ptr&lt;/code&gt; (OpenCV), and others. JavaCPP provides a new transparent bridge to any such references by holding on to a set of two pointers for each native object: the actual pointer of the object to access the data and call functions, and an “owner pointer” corresponding to a smart pointer allocated on the heap, which gets accessed only during deallocation when applying the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;delete&lt;/code&gt; operator. Check the documentation of the &lt;a href=&quot;http://bytedeco.org/javacpp/apidocs/org/bytedeco/javacpp/annotation/SharedPtr.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@SharedPtr&lt;/code&gt;&lt;/a&gt; annotation and the associated C++ template &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SharedPtrAdapter&lt;/code&gt; for more information.&lt;/p&gt;

&lt;p&gt;On top of that, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pointer&lt;/code&gt; now also checks for the “org.bytedeco.javacpp.nopointergc” system property, and if “true”, disables completely the garbage collector safety net, potentially saving a significant amount of time for some applications. To make sure that yours does not rely on the garbage collector for any deallocation, we have also added debug messages that are logged when a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pointer&lt;/code&gt; gets allocated, collected as garbage, and eventually deallocated. They can be captured by setting the “org.bytedeco.javacpp.logger” system property to “slf4j”, and by setting the log level to “debug”, for example, via the “org.slf4j.simpleLogger.defaultLogLevel” system property in the case of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SimpleLogger&lt;/code&gt; from &lt;a href=&quot;http://www.slf4j.org/&quot;&gt;SL4J&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In closing, let us give credit where credit is due. Cyprien Noel was the one that not only brought up all these ideas, but helped to implement them, and tested them out for their own framework of &lt;a href=&quot;http://yahoohadoop.tumblr.com/post/129872361846/large-scale-distributed-deep-learning-on-hadoop&quot;&gt;Caffe-on-Spark&lt;/a&gt;. Discussions with Adam Gibson were also extremely fruitful, providing valuable feedback. They have since adopted JavaCPP for their own use as part of &lt;a href=&quot;http://deeplearning4j.org/&quot;&gt;Deeplearning4j&lt;/a&gt;. Though grateful to them and everyone else who helped out, there is still much work to be done. If you are interested by where this is going, or would like to make your own recommendations and contributions, be sure to contact us via the &lt;a href=&quot;http://groups.google.com/group/javacpp-project&quot;&gt;mailing list from Google Groups&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp/issues&quot;&gt;issues on GitHub&lt;/a&gt;, or &lt;a href=&quot;https://gitter.im/bytedeco/javacpp&quot;&gt;the chat room at Gitter&lt;/a&gt;. Thank you for your interest, and enjoy!&lt;/p&gt;
</description>
        <pubDate>Sun, 25 Oct 2015 00:00:00 +0000</pubDate>
        <link>http://bytedeco.org/news/2015/10/25/moving-to-java-se-7/</link>
        <guid isPermaLink="true">http://bytedeco.org/news/2015/10/25/moving-to-java-se-7/</guid>
      </item>
    
      <item>
        <title>Now offering software under the Apache License</title>
        <description>&lt;p&gt;To facilitate its adoption in commercial applications such as &lt;a href=&quot;http://deeplearning4j.org/&quot;&gt;Deeplearning4j&lt;/a&gt;, the core software of &lt;a href=&quot;https://github.com/bytedeco/javacpp&quot;&gt;JavaCPP&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets&quot;&gt;JavaCPP Presets&lt;/a&gt;, and &lt;a href=&quot;https://github.com/bytedeco/javacv&quot;&gt;JavaCV&lt;/a&gt; has been relicensed to offer users the &lt;a href=&quot;http://www.apache.org/licenses/LICENSE-2.0&quot;&gt;Apache License, Version 2.0&lt;/a&gt; as a new choice of license. No large technical changes has otherwise occurred, but we believe these core components have acquired a stable enough existence to merit an increment in their major version number to 1.0. Moreover, this way we keep a meaningful relationship between our version numbers and the ones of &lt;a href=&quot;http://opencv.org/&quot;&gt;OpenCV&lt;/a&gt;, which has recently seen large changes in its API and has been updated to version 3.0.&lt;/p&gt;

&lt;p&gt;In other news, we now provide &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/cuda&quot;&gt;presets for CUDA&lt;/a&gt;, mapping close to the entirety of its API, including &lt;a href=&quot;https://developer.nvidia.com/cudnn&quot;&gt;cuDNN&lt;/a&gt;, for which no other wrappers that we are aware of currently exist. We hope that, along with the &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets/tree/master/caffe&quot;&gt;presets for Caffe&lt;/a&gt;, which are as far as we know also still a unique offering of ours, this will provide some useful tools to the new exciting world of deep learning.&lt;/p&gt;

&lt;p&gt;As usual, if you have any questions, problems, or would like to contribute, but are unsure how to proceed, please feel free to share your concerns on the &lt;a href=&quot;http://groups.google.com/group/javacpp-project&quot;&gt;mailing list of JavaCPP&lt;/a&gt;, on the &lt;a href=&quot;http://groups.google.com/group/javacv&quot;&gt;one for JavaCV&lt;/a&gt;, or via “issues” on GitHub. We are looking forward to work with you in the future. Have fun!&lt;/p&gt;
</description>
        <pubDate>Sun, 12 Jul 2015 00:00:00 +0000</pubDate>
        <link>http://bytedeco.org/news/2015/07/12/now-apache-license/</link>
        <guid isPermaLink="true">http://bytedeco.org/news/2015/07/12/now-apache-license/</guid>
      </item>
    
      <item>
        <title>Introducing JavaCV frame converters</title>
        <description>&lt;p&gt;To supplement the long-standing functionality of &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/CanvasFrame.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CanvasFrame&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/FrameGrabber.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FrameGrabber&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/FrameRecorder.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FrameRecorder&lt;/code&gt;&lt;/a&gt;, and their implementation classes found in JavaCV, we are introducing the concept of &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/FrameConverter.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FrameConverter&lt;/code&gt;&lt;/a&gt; starting with version 0.11, released today. Other more minor changes have been made to all the components since version 0.10, so be sure to check out the repositories on GitHub: &lt;a href=&quot;https://github.com/bytedeco/javacpp&quot;&gt;JavaCPP&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacpp-presets&quot;&gt;JavaCPP Presets&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/javacv&quot;&gt;JavaCV&lt;/a&gt;, &lt;a href=&quot;https://github.com/bytedeco/procamcalib&quot;&gt;ProCamCalib&lt;/a&gt;, and &lt;a href=&quot;https://github.com/bytedeco/procamtracker&quot;&gt;ProCamTracker&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/FrameConverter.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FrameConverter&lt;/code&gt;&lt;/a&gt;, in short, allows the user to share easily the same audio samples or video image data among different APIs, but without coupling their applications to all of those APIs. For example, JavaCV currently ships with &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/AndroidFrameConverter.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AndroidFrameConverter&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/Java2DFrameConverter.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Java2DFrameConverter&lt;/code&gt;&lt;/a&gt;, and &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/OpenCVFrameConverter.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OpenCVFrameConverter&lt;/code&gt;&lt;/a&gt; to let users represent image data as either &lt;a href=&quot;http://developer.android.com/reference/android/graphics/Bitmap.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;android.graphics.Bitmap&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;http://docs.oracle.com/javase/6/docs/api/java/awt/image/BufferedImage.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;java.awt.image.BufferedImage&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;http://bytedeco.org/javacpp-presets/opencv/apidocs/org/bytedeco/javacpp/opencv_core.IplImage.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IplImage&lt;/code&gt;&lt;/a&gt;, or &lt;a href=&quot;http://bytedeco.org/javacpp-presets/opencv/apidocs/org/bytedeco/javacpp/opencv_core.Mat.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mat&lt;/code&gt;&lt;/a&gt;. The plain old data class adopted by JavaCV is &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/Frame.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Frame&lt;/code&gt;&lt;/a&gt;, which does not itself depend on either Android, FFmpeg, Java 2D, or OpenCV. A user could for example grab and record frames using &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/FFmpegFrameGrabber.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FFmpegFrameGrabber&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/FFmpegFrameRecorder.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FFmpegFrameRecorder&lt;/code&gt;&lt;/a&gt;, without requiring anything more than FFmpeg. We could further display those frames with &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/CanvasFrame.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CanvasFrame&lt;/code&gt;&lt;/a&gt;, creating a dependency on Java 2D, or alternatively, on Android, if we transfer the frames to video memory with &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/AndroidConverter.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AndroidFrameConverter&lt;/code&gt;&lt;/a&gt;. To further process the data, one might start using &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/OpenCVFrameConverter.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OpenCVFrameConverter&lt;/code&gt;&lt;/a&gt;, automatically creating a dependency on OpenCV that was not present until that point. We intentionally designed the API to be as easy to use as possible, but at the same time as efficient as possible, eliminating data copies whenever the underlying APIs allow. A typical usage scenario might look like this:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;   &lt;span class=&quot;nc&quot;&gt;FFmpegFrameGrabber&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grabber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FFmpegFrameGrabber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;video.mp4&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
   &lt;span class=&quot;nc&quot;&gt;AndroidFrameConverter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;converterToBitmap&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AndroidFrameConverter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
   &lt;span class=&quot;nc&quot;&gt;OpenCVFrameConverter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ToMat&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;converterToMat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;OpenCVFrameConverter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ToMat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

   &lt;span class=&quot;c1&quot;&gt;// Grab an image Frame from the video file&lt;/span&gt;
   &lt;span class=&quot;nc&quot;&gt;Frame&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;frame&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grabber&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;grab&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
   &lt;span class=&quot;c1&quot;&gt;// Perform a shallow copy to represent frame as a Mat&lt;/span&gt;
   &lt;span class=&quot;nc&quot;&gt;Mat&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;converterToMat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;convert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
   &lt;span class=&quot;c1&quot;&gt;// Do some processing on mat with OpenCV&lt;/span&gt;
   &lt;span class=&quot;nc&quot;&gt;Mat&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;processedMat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
   &lt;span class=&quot;c1&quot;&gt;// Convert processedMat back to a Frame&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;frame&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;converterToMat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;convert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;processedMat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
   &lt;span class=&quot;c1&quot;&gt;// Copy the data to a Bitmap for display or something&lt;/span&gt;
   &lt;span class=&quot;nc&quot;&gt;Bitmap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bitmap&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;converterToBitmap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;convert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It is also possible to pass a &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/Java2DFrameConverter.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FrameConverter&lt;/code&gt;&lt;/a&gt; in a generic way to prevent unnecessary processing of data, for example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;FrameConverter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;converter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;I&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;someCondition&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nc&quot;&gt;Frame&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;frame&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;converter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;convert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Process frame.image...&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As a side note, to implement &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/Java2DFrameConverter.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Java2DFrameConverter&lt;/code&gt;&lt;/a&gt; we used code previously found inside the &lt;a href=&quot;http://bytedeco.org/javacpp-presets/opencv/apidocs/org/bytedeco/javacpp/helper/opencv_core.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opencv_core&lt;/code&gt; helper class&lt;/a&gt;. On Android, this was problematic because it would cause the log file to fill up with warnings about classes missing from the &lt;a href=&quot;http://docs.oracle.com/javase/6/docs/api/java/awt/package-summary.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;java.awt&lt;/code&gt;&lt;/a&gt; package. Moving that code out fixed this annoyance. As a less happy consequence, to recover the functionality that was lost, existing users need to refactor their code based on a combination of &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/Java2DFrameConverter.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Java2DFrameConverter&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;http://bytedeco.org/javacv/apidocs/org/bytedeco/javacv/OpenCVFrameConverter.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OpenCVFrameConverter&lt;/code&gt;&lt;/a&gt;. To limit these kinds of breaking changes, the features are still very limited, but in a way, this is intentional. It allows users to focus on what is missing, rather than on figuring out how to use everything. We are aware of no precedent to a framework like JavaCV that has attempted to bridge the gap between multimedia and computer vision across platforms.&lt;/p&gt;

&lt;p&gt;In any case, we hope that overall you find this “frame processing” technique practical for your own applications, and as usual, if you have any questions, problems, or would like to contribute, but are unsure how to proceed, please feel free to share your concerns &lt;a href=&quot;http://groups.google.com/group/javacv&quot;&gt;on the mailing list&lt;/a&gt; or via “issues” on GitHub. Enjoy and thank you for your continued interest!&lt;/p&gt;
</description>
        <pubDate>Sat, 04 Apr 2015 00:00:00 +0000</pubDate>
        <link>http://bytedeco.org/news/2015/04/04/javacv-frame-converters/</link>
        <guid isPermaLink="true">http://bytedeco.org/news/2015/04/04/javacv-frame-converters/</guid>
      </item>
    
  </channel>
</rss>
