The Java Tensorflow library does not seem to be using GPU

Please make sure that this is a bug. As per our GitHub Policy, we only address code/doc bugs, performance issues, feature requests and build/installation issues on GitHub. tag:bug_template
System information

Have I written custom code (as opposed to using a stock example script provided in TensorFlow): YES
OS Platform and Distribution (e.g., Linux Ubuntu 16.04): Ubuntu 18.04
Mobile device (e.g. iPhone 8, Pixel 2, Samsung Galaxy) if the issue happens on mobile device: NO
TensorFlow installed from (source or binary): from https://oss.sonatype.org/
TensorFlow version (use command below): 2.3.1
Python version: 3.7.7
Bazel version (if compiling from source): NO
GCC/Compiler version (if compiling from source): NO
CUDA/cuDNN version: 10.1
GPU model and memory: Tesla K80, compute capability 3.7 (but we also tested this on Tesla V100 7.0 compute capability)

You can collect some of this information using our environment capture script
You can also obtain the TensorFlow version with
python -c "import tensorflow as tf; print(tf.GIT_VERSION, tf.VERSION)"
Here is the result of the capture script:
tf_env.txt
Describe the current behavior
We tested the new Tensorflow Java API (not the legacy one). The brand new version released in October 2020. We tested it on some machines including Azure Databricks NC6_v3 and Azure Virtual Machines (the capture log is from the virtual machine). I noticed that in case of no GPU available the library falls back to CPU. And this is fine. However we also measured the time for some example processing (a few vector operations). And we see that there is no significant difference between processing time on GPU and on CPU. It looks as it is not using GPU, even if this is present (we tried two graphic cards: Tesla K80 with compute compatibility 3.7 and Tesla V100 with compute compatibility 7.0). In both cases we do not see any difference in processing time.
Describe the expected behavior
Expected behaviour is to get execution times much better if the program is executed on a machine with GPU present.
Code to reproduce the issue
Provide a reproducible test case that is the bare minimum necessary to generate the problem.
We used the following java program:
HelloTensorFlow_java.txt
pom_xml.txt
The source was compiled to class file and it was run via the following command:
java -classpath protobuf-java-3.8.0.jar:ndarray-0.2.0.jar:javacpp-1.5.4.jar:javacpp-1.5.4-linux-x86_64.jar:tensorflow-core-api-0.2.0.jar:tensorflow-core-api-0.2.0-linux-x86_64-gpu.jar:tensorflow-core-platform-gpu-0.2.0.jar:. HelloTensorFlow
The listed libraries were downloaded from https://oss.sonatype.org/.
Other info / logs
Include any logs or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached.
The enclosed program issues the following log:
log.txt
From the log you may see that the GPU was present and recognized.
However the execution time did not differ, when we started it with GPU and without.

Hi @tmichniewski ,
You need to assign explicitly an operation to a GPU device, like explain here, otherwise it will fallback to CPU.
Now, there is an ongoing effort to make device selection easier on TF Java, as right now you need unfortunately to use the lower-level API for building an operation.
For example, instead of simply call tf.math.add(x, y), you need to do something like:
DeviceSpec gpuSpec = DeviceSpec.newBuilder().deviceType(DeviceType.GPU).deviceIndex(0).build();
...
graph.opBuilder(Add.OP_NAME, "Add1").setDevice(gpuSpec).addInput(x.asOutput()).addInput(y.asOutput()).build();

You can also log device placement by passing explicitly a ConfigProto message when instantiating your Session, using this constructor

Hello @karllessard,
Referring to the first recommendation: are you sure that we could call deviceType on DeviceSpec.newBuilder()? As my IntelliJ complains about this.

Basically I am looking for simplest solution, just for testing the performance.

BTW - I am using version 0.2.0.

@tmichniewski , to be honest I haven't tested the code snippet I've posted you but something around that should work. You can also simply pass directly the device spec as a string for now, as described here.  I'll be curious to see what device placement logging is telling you as well, if you get a chance to activate it.

I already used hardcoded string "/GPU:0".

Hello @karllessard,
Well, I made a tests on Azure Databricks machine NC6s_v3 with graphic card Tesla V100 compute comtability 7.0.
With device set to "/CPU:0" the execution time is 0.23s.
With device set to "/GPU:0" the execution time is 0.62s.
So not only it does not reduce the execution time but also it increases it.
The current code is as follows:
HelloTensorFlow_java.txt

BTW - on this cluster in Python we got following times:
CPU 1.00s.
GPU 0.25s.
PythonHelloTensorFlow_py.txt
So in Python GPU is 4 times faster in this exercise. But in Java GPU version is slower than CPU version.

Maybe I should also set the device to the session or graph?

But then it would make no sense to set it on operation level.
Do you have any working example of how to perform let say vector addition on GPU?

Why not try running the Java version in eager mode like the python is?

Firstly, because eager mode is only for development, not production.
Secondly - well - for tests of course I might use it, but do you have some working example with suggestion how to pass the device on which TF is being executed? Originally I used it, but Karl (in his first comment) sugested to use low level API.

But the python example is in eager mode, so let's rule out the difference in the TF runtime engine first, before moving on to issues inside the Java API. I'm sure there are speed issues in the Java API, but best start with equivalent metrics first.

@Craigacp Hello Adam,
I am not comparing Python times to Java times. I try to compare GPU time to CPU time. Python code was only to show that GPU version was roughly 4x faster then CPU. Or in other words - I try to run TF Java API on GPU. So far without success.
Right - in Python it was in eager mode. The same in original Java version I guess. But this issue is about how to make java API to execute on GPU. So far I was pointed to the low level API, but this does not work. That is way I ask for:

either some hint of how to correctly pass the device to the API to make it work on GPU (in eager mode or static one),
or some link to some working example (the API is quite fresh and there are no that many examples/tutorials in the net).

Moreover, Karl also pointed me in his third comment to the following description, which clearly states that if there is a choice, then GPU takes precedence:
"If a TensorFlow operation has both CPU and GPU implementations, by default the GPU devices will be given priority when the operation is assigned to a device. For example, tf.matmul has both CPU and GPU kernels. On a system with devices CPU:0 and GPU:0, the GPU:0 device will be selected to run tf.matmul unless you explicitly request running it on another device."

I cannot think of any reason why running graph ops on a GPU in Java would be slower than in Python, since this is all handled by the C++ core library shared by both languages. So if it is really what we are observing, then it has to be a misconfiguration somewhere.
Another idea, can you check @tmichniewski if the performance goes back to normal if you remove the line inside the loop where you fetch the result from the tensor? Maybe you are fetching data from the GPU memory to the JVM and that is doing extra copies that are not required when using Python?

I also do not believe that Java version could be slover than Python one. But this is not the issue here. The problem is that it seems that GPU is not used at all.
The previous version of this library 2.3.0, the so called lagacy (since last weekend) was saying that the kernel image was incorect and there was suggestion to build TF from sources. But here the library silently falls back to CPU and you never know whether GPU is used except by measuring time.
Refering to second paragraph, well, I thought that it is always necessary to get the data back from tensor. BTW, we read only one double value, because the last operation in graph is reduce_sum, so we take 8 bytes instead of big vector. Therefore it cannot be reason of slow performance.
PS.
Do you test it on GPU? I guess so, therefore I think you should have some observations and know-how of how to make it work on GPU.

Maybe there is some issue with graphic card compute capability. In our case it is 7.0 and was also 3.7. Does this library work with cards with such parameters? If not then this would explain why it silently falls back to GPU.
Or maybe the issue is that the choice of GPU device is not defined correctly. So I ask for some example of how to do this. For example how to perform vector addition on GPU. Very simple example. So far I provided two versions, eager and graph, but both are not using GPU.

Sorry @tmichniewski but I'm not personally using GPUs nor have access to one right now so I might not be the best person to provide you a concrete working example of this here, maybe @zaleslaw or @saudet can chime in?
Again, I think logging device placement might reveal some explanations as well, see the Session constructor link I've provided earlier.

I haven't been testing it really closely, but I know at least @roywei and @lanking520 have been using the GPU builds without too much trouble.

Hello @karllessard, @saudet, @roywei and zaleslaw and lankin520,
I also could confirm that it is possible to use GPU builds without trouble. But the key question here is whether the GPU builds really use GPU if it is present on a machine. My tests seems to be telling that NO, they are not using GPU. At least so far I don't know how to make it use GPU.
I provided two sample Java programs:
The first with simple vector computation where I expected that providing gpu versions of libraries should make TF use GPU, but it was not the case.
The second example is after Karl's recommendation, where I additionally specified the device in the graph operations. Also without success.
Now, since this library silently falls back to CPU if GPU is not present or for some reason the library is not willing to use it, then how do you perform the unit tests?
One possibility it by comparing the execution times, but this is really delicate. What are the other possibilities? Because I think all the tests may be successful after the library falls back to CPU, while all of them should fail in case of GPU present on a machine and requested.
In my opinion there should be a possibility in the API to request computation on GPU and if this is not satisfied, then the unit tests and the whole API should raise an exception saying that cannot be executed on requested GPU due to some reason.
Concluding I repeate my original issue - How to make Tensorflow Java API convince to use GPU?
Please point me to any working example or provide any working hint. Could you?
PS. By working I understand not only working, but also using GPU if present.

@tmichniewski hi, we were able to use GPU to run inference. For GPU use case, you need to make sure your operator and model are loaded on GPU device. You can also try with DJL that wrap TF Java package and provide some ease to automatically do GPU switch during runtime.
You can play around with our Jupiter notebook in Java http://docs.djl.ai/jupyter/tensorflow/pneumonia_detection.html
If you have GPU device and install CUDA 10.1, it will use GPU out of box without a single line of the code changes.

Hello @lanking520,
Refering to:
"we were able to use GPU to run inference. For GPU use case, you need to make sure your operator and model are loaded on GPU device."
seems to be contradicting to your next statement:
"If you have GPU device and install CUDA 10.1, it will use GPU out of box without a single line of the code changes."
So far I added setDevice("/GPU:0") to every graph operation like in the code below:
HelloTensorFlow_java_2.txt
just to be 100% sure where the computation is being executed.
But the results I get on my test computation on 100 mln entries vectors (so big enough) executed 1000 times do not show any time difference when executed on GPU or CPU. In fact the results are almost the same (6.0s. vs. 6.1s.).
On the contrary, when I executed the same test on Python in eager mode I got 4.5s. on GPU and 259s. on CPU, so the difference is huge and visible. Therefore I wonder why in case of using Java API I do not see the same difference? Could you explain it?
python_test_2.txt
BTW - I am not comparing Python to Java or eager to graph execution. I am comparing GPU to CPU execution, where in Python I see huge defference while in Java I see no difference.
PS.
I do not want to run these DJL samples which bring a lot of new elements to the picture and new changing parameters, so in general this may only complicate my tests instead of simplifying them. Moreover, if DJL wraps TF Java package, then it will change nothing if I do not see that TF java package is working well on GPU.
Maybe it is like this that TF Java API is well optimized to Deep Learning computations while not exactly to very simple vector operations.

In general I think that there might be three possibilities:

First possibility is that I might be doing something wrong in my test program, however I think you had a chance to look at it. Any way, if this is the case, then I simply ask for some support or just a reference to some simple example program, but with vector operations, not with sophisticated neural networks computations.
Second option is that the TF Java API might not be using GPU. In this case I would ask for some hints of how to force it to use GPU.
Finally there also might be some bug in the API which sees GPU and tries to use it but silently falls back to CPU. In this case you will know best how to handle this.

So my question is which situation we are dealing with? Or how to diagnose it?

Hello @karllessard,
Refering to DeviceSpec.newBuilder().deviceType(...) - I cannot use this construction because deviceType metod is called on object Builder, which is package-private and cannot be used outside of org.tensorflow package. This is why I could not use it.
PS. This is is just a comment, because the code snippet you provided was perfectly valid, but only for you. :-)

Mr. Tomasz, I'm also faced with a similar issue with the API (missed method
on operand level, only on builder).
Do you have a chance to experiment on the previous version of Java API
(1.15, for example)? I found a very big difference for LeNet model training
on GPU and without. It could be important to understand what was missed
when we switched from 1.x to 2.x.
Agree, that DeviceSpec could not be used directly in API, but could be used
as a builder to build a correct device string (if it's required).
Alex
ср, 4 нояб. 2020 г. в 17:02, Tomasz Michniewski<EMAIL_ADDRESS>
Hello @karllessard https://github.com/karllessard,
Refering to DeviceSpec.newBuilder().deviceType(...) - I cannot use this
construction because deviceType metod is called on object Builder, which is
package-private and cannot be used outside of org.tensorflow package. This
is why I could not use it.
PS. This is is just a comment, because the code snippet you provided was
perfectly valid, but only for you. :-)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/tensorflow/java/issues/140#issuecomment-721749110,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAJEUHI6MBMQP66UE4CCQWLSOFNGJANCNFSM4TIZUTNQ
.

Hello Alex @zaleslaw,
1.15.0 - so the API of Tensorflow 1 which had recent commit in Maven Repository in October 2019 (we skipped this from the very beginning as obsolete),
2.3.0 - so called Lagacy API since last weekend (in Python and Java API+Scala, but this version did not work in Java/Scala on our machines with GPU compute capability 3.7 and 7.0 - it was always saying that image in incorrect and we should build TF from sources),
0.2.0 - the newest API produced on October 2020 (in Java API).
I experimented on Azure Databricks clusters, but also on Azure Virtual Machines instantiated on request.
So far I had not a single result with Java API where I could see - OK, computing on GPU is X times faster. Not a single result.
We managed to see such results only in Python, but never in Java API. That is why I started wordering what is wrong. Because basically we should be able to observe that GPU processing is sometimes faster, the same as in Python we see.
At the moment we focus only on this new API, as last week we spent a lot of time on this legacy version 2.3.0. We even started to analyse how to build it from sources.
Well - maybe there is also the same issue like in 2.3.0 - I mean the Java API recognizes that the graphic card compute capability is too low and silently falls back to CPU.
In my opinion I managed to force the API to use the specified GPU. But apparently it is not being used. Maybe this logic to fall back to CPU should be guarded somehow and if the requirement is to process on GPU and GPU cannot be used (is not present or has wrong compute capability), then maybe the error should be thrown, not a warning or nothing. You know, the developer/user requests to process on GPU, then if this is not possible, then "blue screen". Otherwise we end up in situations like this that we discuss what might be going on here.

In our test platform, we benchmarked ResNet50 Image classification model, there is a small gap between Python GPU and Java GPU (you can find my issue filed in here). However, if you compare with CPU (AWS EC2 C5.2xlarge) it's around 40ms and GPU (AWS EC2 p3.2xlarge) is around 5.7ms. GPU is in fact much faster than CPU.
But it seemed the TF2 doing something weird that causing everything slow. We also did some benchmark on the cpu performance and see TF1 CPU latency is 2/3 of TF2 on Resnet 50 model with Java api. But same problems on Python too... So nothing to blame. :)

Refering to your last statement, well, I setup another cluster without GPU, so only CPU with similiar core class and got 7.1s.
Then I run this on a laptop with CPU only and also had similiar results like 6.6s. So these results in Java on machines with CPU only are much more close to Python on GPU.
But of course these are just comments on these results. Let us focus on facts. To get the facts I need some method to be able to check where my processing is executed. Is it possible to turn some logging, where the API would tell with 100% certainty on which device it us executing?
You know what, I believe that in your test you have better results on GPU than CPU. But you have a different machine than I. Could you confirm that in my case it is impossible that TF Java API falls back to CPU due to some reason, for example during compute compatibility. Former Java API version 2.3.0 had problems with such compute cspabilities. But new version 0.2.0 might just fall back to CPU instead of issuing error. This is how I interpret my test results. Because GPU and CPU results are almost the same.
Now, the question is how to diagnose it. So far it is far from intuitive.

Is it posibble that TF Java API checks my graphic card Tesla V100 and decides that compute capability 7.0 is wrong/too weak and silently falls back to CPU. Is it possible?

TF Java uses the same placement engine and logic as Python, because it all happens in the C layer. I'm trying to replicate your issue at the moment, but it triggered a full TF GPU recompile and it's taking a little while on the test VM I've got.

Hello Adam @Craigacp,
Have you got any results?

Hi @tmichniewski , sorry if I continue to ask but can you please enable log device placement in your session and share with us the output logs? I think it is more reliable than comparining the speed to know what has been placed on a CPU or GPU.
For example, I took your original code and change try (Graph g = new Graph(); Session s = new Session(g)) {... for this:
ConfigProto config = ConfigProto.newBuilder(ConfigProto.getDefaultInstance()).setLogDevicePlacement(true).build();
try (Graph g = new Graph(); Session s = new Session(g, config)) { ...

and now it gives me the following output:
2020-11-05 09:08:44.176590: W external/org_tensorflow/tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'libcudart.so.10.1'; dlerror: libcudart.so.10.1: cannot open shared object file: No such file or directory
2020-11-05 09:08:44.176822: I external/org_tensorflow/tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
Hello TensorFlow 2.3.1
2020-11-05 09:08:44.406991: I external/org_tensorflow/tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN)to use the following CPU instructions in performance-critical operations:  AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2020-11-05 09:08:44.412857: I external/org_tensorflow/tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcuda.so.1
2020-11-05 09:08:44.418527: E external/org_tensorflow/tensorflow/stream_executor/cuda/cuda_driver.cc:314] failed call to cuInit: CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected
2020-11-05 09:08:44.418553: I external/org_tensorflow/tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (xps): /proc/driver/nvidia/version does not exist
2020-11-05 09:08:44.419212: I external/org_tensorflow/tensorflow/core/common_runtime/direct_session.cc:360] Device mapping: no known devices.

Hello Karl @karllessard,
Sure, I will test it tomorow.
PS. Thanks for this snippet, this is the kind of support I was hoping for.
Tomek

Hello Karl @karllessard,
I made two tests, both witj vectors of 100 mln elements and the computation is executed 1000 times. Here are the results:
GPU.txt
CPU.txt
Now - does it prove that in first case the computation was executed on GPU?
If so, then looking at the results: GPU 6.05s., CPU 5.74s. I worder why CPU is even faster than GPU, or at least GPU is not faster.
What is wrong with this test?
Maybe the computation is too simple? Maybe vectors are too small. What makes GPU version work as long as CPU one?
OK, I know that TF originally was designed for bigger workloads, for example ML models. But ML computation consists of such numerical computations, but in much bigger scale. So is the scale the problem here? Maybe using GPU generates additional overhead to pass the computation to GPU? Maybe this consumes the advantages of using GPU?
What is wrong with TF Java APIused like this example?
BTW - we also noticed that TF is a few times faster than popular NumPy on Python. But in Python we also observed that GPU computation was 4-5 times faster than on CPU. So why in case of Java API the times are roughly the same (time on GPU is more or less the same as on CPU)?

Well, in fact in Python this test (1000 times executed the given expression in eager mode on vectors of 1mln elements) lasted:
0.23s. on GPU
1.13s. on CPU
But, when we increased the vector size to 100mln (like in Java example), then we got:
4.50s. on GPU
259.4s. on CPU
Isn't it a proof that GPU version is much faster?
So why on the same machine we have so strange results in case of Java API?
Firstly, even if there is a bug which reports using GPU or CPU, but under cover always uses GPU (this is also possible), then why Java API is slower than Python (6s. vs. 4.5s.)?
Moreover, when I run these tests with Java API 10000 times I got:
8.0s. on GPU
6.5s. on CPU
How to interpret these results?

Hello Adam @Craigacp,
Did you manage to finish your test on this sample program?

Firstly, even if there is a bug which reports using GPU or CPU, but under cover always uses GPU (this is also possible), then why Java API is slower than Python (6s. vs. 4.5s.)?

Make sure XLA is enabled, see issue https://github.com/tensorflow/java/issues/134#issuecomment-721538573

How to use XLA in Java API?
In Python this is simple: @tf.function(experimental_compile=True) according to:
https://www.tensorflow.org/xla/tutorials/compile?hl=en

Hi @tmichniewski , we can continue to drill down in the problem a bit to continue our investigation, thanks for helping. What I would suggest now is to compare the performances if you stop fetching the outputs, to give us a better idea on the impacts of doing memory transfers between CPU and GPU. Maybe Python have better optimizations for doing this, we'll see.
Can you please change your loop for something like this and try again on both GPU and CPU?
 for (int i = 0; i < 1000; i++) {
        s.runner().addTarget(z).run();
 }

Also, like @Craigacp suggested previously, if your Python comparable is this script, then maybe you want to run in eager mode in Java as well. That would mean that your code would look like something this:
import org.tensorflow.*;
import org.tensorflow.op.Ops;
import org.tensorflow.op.core.Constant;
import org.tensorflow.types.TFloat64;

import java.util.Arrays;

public class HelloTensorFlow {
  public static void main(String[] args) {
    System.out.println("Hello TensorFlow " + TensorFlow.version());

    double[] pi = new double[1_000_000];
    Arrays.fill(pi, 3.14); // Pi
    double[] e = new double[1_000_000];
    Arrays.fill(e, 2.72); // e
    Ops tf = Ops.create();

    // Tensor<TFloat64> aTensor = TFloat64.scalarOf(3.456);
    Constant<TFloat64> a = tf.constant(3.456);
    Constant<TFloat64> b = tf.constant(0.5);
    Constant<TFloat64> x = tf.constant(pi);
    Constant<TFloat64> y = tf.constant(e);

    long startTime = System.nanoTime();

    for (int i = 0; i < 1000; i++) {
      // x * y * a / x + b where a = 3.456 and b = 0.5
      Operand<TFloat64> z = tf.reduceSum(tf.math.add(tf.math.div(tf.math.mul(tf.math.mul(x, y), a), x), b), tf.constant(0));

      // Uncommenting this line will force additional I/O between GPU and CPU, testing both cases could be interesting
      // System.out.println(z.data().getDouble());
    }
    long stopTime = System.nanoTime();
    System.out.println("Time [s.] " + (double)(stopTime - startTime) / 1000_000_000);
  }
}

Running @karllessard's snippet in eager mode is definitely using the GPU as it takes up all the GPU memory and errors out (because there hasn't been anything to free the tensors all those operations create).
The Python version you put is using fp32 and the Java is using fp64, so that's not a fair comparison (as CPUs don't slow down as much as GPUs when doing fp64 math).
Comparing the CPU and GPU in Java in graph mode I get roughly the same time for both of them, as with a simple matmul of two 10000x10000 matrices. The device placement fails if you give it a device that doesn't exist, and that's our view into the TF C library, so it might be doing something below the Java API level. The fact that the placement fails suggests it is building the nodes in the right place. Using CUDA_VISIBLE_DEVICES=  on the CPU run doesn't make that slower, so it's not ignoring the CPU placement and putting things on the GPU anyway.
Turning off the fetching of the result out of the loop makes both CPU and GPU faster by roughly the same amount.
My recommendation would be to try running a real workload like ResNet inference with and without CUDA_VISIBLE_DEVICES=  (note the space after the equals), as that turns on and off the GPU. I don't have time to do such an experiment at the moment, but I might get some time next week.

Hello Karl @karllessard,
Referring to first test (with "s.runner().addTarget(z).run();") I made it twice (in both cases I increased the size of the vectors to 100_000_000:

First test when I referenced the GraphOperation sum - these operations with direct setDevice. I got following results:
FirstTestJava.txt
FirstTestGPU.txt
FirstTestCPU.txt
As you can see the GPU (6.23s.) version is even slightly slower than CPU (6.06s.). Moreover, when I started this test on my Laptop I got 7.02s. (only CPU).
Second test when I referenced the z Operand from eager mode. Then I got following results:
SecondTestJava.txt
SecondTestGPU.txt
SecondTestCPU.txt
In this test GPU time 6.26s., CPU time 6.26s., and laptop time 6.80s.
Generally GPU is more or less the same as CPU.

Hello Karl @karllessard,
Referring to your next longer test, where "Operand z" is instantiated inside the for loop - well, in this case on both my laptop and Databricks machine with GPU I got OutOfMemory error even though there were vectors of 1_000_000 size, while in my previous tests I used 100_000_000 vectors, so 100x bigger.
OOM.txt
I suspect it might be due to the fact that "z" is instantiated 1000 times inside a loop.
Referring to:
// Uncommenting this line will force additional I/O between GPU and CPU, testing both cases could be interesting
// System.out.println(z.data().getDouble());

I think this test would test time of copying one double value (8 bytes) plus cost of println. In case of copying data between memory of GPU and CPU copying 8 bytes is nothing really serious. That is why the test expression had final reduce to aviod copying vector data between processors.

Hello Adam @Craigacp,
I don't want to do bigger tests because bigger and more complicated tests means more changing parameters which influence the results. I want to verify whether it makes sense to use Tensorflow Java API to perform vector operations. And what I expect is that I will see some improvement after running on GPU (as in Python case). But in case of Java API so far my expectations were not confirmed.
All these tests seem to prove only that indeed my computation is executed on GPU if such is present, but execution time is more or less the same as on CPU. And I still think that this is strange.

Larger tests will allow us to rule out misconfiguration of our compiled version of libtensorflow vs inefficiencies in the way the Java API passes in results to the graphs or the way the graphs/eager functions are executed. Running a few batches of inference of a reasonable sized model should amortize all the TF Java calling overheads, and hopefully show a speedup, which would indicate that it's a problem with how we call the libtensorflow C library (or how we pass in arguments). If it doesn't show a speedup, then the way we build libtensorflow might be causing some problems.
At the moment it's hard to say what the root cause of the inefficiency is, so more data will help us narrow it down.

Ok, I did another test, results confirm what we observed previously, where running on a GPU takes as long as on the CPU (even longer in this case, in fact). I've run the previous graph but within a loop of 5M iterations. See the following code and the results below:
package mypackage;

import org.tensorflow.*;
import org.tensorflow.op.Ops;
import org.tensorflow.op.core.Constant;
import org.tensorflow.op.core.ReduceSum;
import org.tensorflow.proto.framework.ConfigProto;
import org.tensorflow.proto.framework.GPUOptions;
import org.tensorflow.types.TFloat64;

import java.util.Arrays;
import org.tensorflow.types.TInt32;

public class GPUTest {
  public static void main(String[] args) {
    System.out.println("Hello TensorFlow " + TensorFlow.version());

    double[] pi = new double[1_000_000];
    Arrays.fill(pi, 3.14); // Pi
    double[] e = new double[1_000_000];
    Arrays.fill(e, 2.72); // e

    ConfigProto config = ConfigProto.newBuilder(ConfigProto.getDefaultInstance())
        .setLogDevicePlacement(true)
        .build();

    try (Graph g = new Graph(); Session s = new Session(g, config)) {
      Ops tf = Ops.create(g);

      Output<?> loopInput = tf.placeholder(TInt32.DTYPE).output();

      Output<?> loopOutputs[] = g.whileLoop(
           new Output<?>[] { loopInput },
          (cgraph, inputs, outputs) -> {
            Ops ctf = Ops.create(cgraph);
            outputs[0] = ctf.math.less((Output<TInt32>)inputs[0], ctf.constant(1_000_000)).z();
          },
          (bgraph, inputs, outputs) -> {
            Ops btf = Ops.create(bgraph);

            Constant<TFloat64> a = btf.constant(3.456);
            Constant<TFloat64> b = btf.constant(0.5);
            Constant<TFloat64> x = btf.constant(pi);
            Constant<TFloat64> y = btf.constant(e);

            ReduceSum<TFloat64> r = btf.reduceSum(
                btf.math.add(
                    btf.math.div(
                        btf.math.mul(
                            btf.math.mul(x, y), a),
                        x),
                    b),
                btf.constant(0)
            );
            outputs[0] = btf.withControlDependencies(Arrays.asList(r)).math.add((Operand)inputs[0], btf.constant(1)).asOutput();
          },
          "test_gpu_loop"
      );
      long startTime = System.nanoTime();
      try (Tensor<TInt32> c = TInt32.scalarOf(0);
        Tensor<?> tensor = s.runner()
            .feed(loopInput, c)
            .fetch(loopOutputs[0])
            .run()
            .get(0)) {}
      long stopTime = System.nanoTime();
      System.out.println("Time [s.] " + (double)(stopTime - startTime) / 1000_000_000);
    }

    System.out.println("Bye bye");
  }
}

CPU: 11.65383011 secs
GPU: 18.522389901 secs

Now, we can confirm that most of that time is totally spent in the native TF runtime library that has no interaction with the JVM. Device placement logs shown me as well that the ops were placed on the expected device in both cases. So there might be something missing the native library build that prevent the GPU kernels to operate at full speed. @saudet already mentioned that XLA support is not enabled by default but there must something else missing.

Hello Karl @karllessard,
Is it possible that even the operations were placed on GPU, they are not executed there due to for example wrong (too small) compute capability of GPU?
My understanding of this whole situation is that it seems that the Java program is doing its best and we confirmed that it should use GPU, but at the moment the computation times prove that something weird is happening and apparently the computation is done on CPU or some other problem extends computation time on GPU. This questions the sens of using Java API untill the problem is fixed.

I'll share some results from my side:
I ran on my local machine with NVIDIA card GeForce GTX 1650 the following example
I made minor changes:

10 epochs instead 1 in example
batch_size = 100 instead of 1000 (for the best GPU memory utilization)

Also I set up the session with the following setting:
session = new Session(graph, ConfigProto.newBuilder().setGpuOptions(GPUOptions.newBuilder().setAllowGrowth(true).build()).build());

For 1 epoch:
GPU: 13367 +- 140 ms
CPU: 56156 +- 420 ms
Speed up ~ 4.2
For 10 epochs:
GPU: 106852 +- 1000 ms
CPU: 560519 +- 6900 ms
Speed up ~ 5,24
For 20 epochs:
GPU: 214016 +- 1800 ms
CPU: 1127356 +- 12500 ms
Speed up ~ 5,26
P.S. The speedup for this GPU on 1.15 was closer to 7.2 times on LeNet-like models

Thanks a lot for the investigation @zaleslaw , that is very appreciated and these results are closer to what we can expect from a GPU with TF Java. So I guess the reason we were not observing this delta previously was just that the example that we've been using? My concern though is why in Python the same example shows a performance improvement while it does not in Java, there is still something that we are missing here.

Hello Alexey @zaleslaw,
Could perform additional test on your machine, but this time with our example, which Karl mentioned? We have plain vector computation instead of sophisticated machine learning algorithms.

@tmichniewski will try to reproduce and share results

@tmichniewski @karllessard There are a lot of different code snippets, I used one from here
My results:
GPU:
Time [s.] 2.402464902
Bye bye
test_gpu_loop/Enter: (Enter): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/Merge: (Merge): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/cond/Less: (Less): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/LoopCond: (LoopCond): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/Switch: (Switch): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/body/Mul: (Mul): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/body/Mul_1: (Mul): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/body/Div: (Div): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/body/Add: (Add): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/body/ReduceSum: (Sum): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/body/Add_1: (Add): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/NextIteration: (NextIteration): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/Exit: (Exit): /job:localhost/replica:0/task:0/device:GPU:0
Placeholder: (Placeholder): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/cond/Const: (Const): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/body/Const: (Const): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/body/Const_1: (Const): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/body/Const_2: (Const): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/body/Const_3: (Const): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/body/Const_4: (Const): /job:localhost/replica:0/task:0/device:GPU:0
test_gpu_loop/body/Const_5: (Const): /job:localhost/replica:0/task:0/device:GPU:0

Process finished with exit code 0

CPU:
Time [s.] 1.63166006
Bye bye
test_gpu_loop/Enter: (Enter): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/Merge: (Merge): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/cond/Less: (Less): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/LoopCond: (LoopCond): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/Switch: (Switch): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/body/Mul: (Mul): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/body/Mul_1: (Mul): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/body/Div: (Div): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/body/Add: (Add): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/body/ReduceSum: (Sum): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/body/Add_1: (Add): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/NextIteration: (NextIteration): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/Exit: (Exit): /job:localhost/replica:0/task:0/device:CPU:0
Placeholder: (Placeholder): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/cond/Const: (Const): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/body/Const: (Const): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/body/Const_1: (Const): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/body/Const_2: (Const): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/body/Const_3: (Const): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/body/Const_4: (Const): /job:localhost/replica:0/task:0/device:CPU:0
test_gpu_loop/body/Const_5: (Const): /job:localhost/replica:0/task:0/device:CPU:0

Looks like GPU is slower than CPU, but task is quite small and overhead is great.

Hello @zaleslaw
If the task seems to be too simple it might be increased to vector of 100 mln. elements. In Python we observed that GPU version was much faster than CPU one. This was like seconds to minutes. Why noone observed it on Java API? What is wrong in Java API?

Expanding the vector size doesn't stress the right places. If (as it appears given the information we have) there's something going wrong with the initial setup and copy then increasing the vector size bumps that as well as the computational workload.
We're not sure what's happening yet, clearly something is wrong but we've not got a root cause.

Is there anyone who would be able to debug it, to check what is the cause of the problem? Why it is so difficult?

Hi @tmichniewski , I think what's makes it a bit difficult for us to debug is that:

GPUs are handled entirely by the TensorFlow C++ library and normally Java should have nothing to do with it, so we need to dig deeper into the TensorFlow runtime and Python client to understand what is going wrong with your test application, while our expertise is more on the Java bindings themselves.

Not all of us, including me, has access to a local GPU machine.

This is a community-driven project and all collaborators are working on it on their free will and time.

So yes I think we are all interested to understand better the problem and meanwhile if you can please continue your investigations, the project would surely benefit from it.
Thanks,
Karl

Hello Karl @karllessard,
Ad.1. Have you looked at Python TF client to see how it uses the c++ library and what are the differences. In fact Java TF API should mimic what Python client is doing, so it is worth analysing even without my issue reporting.
Ad.2. Sure, if you provide me with any source code (recommended improvements, configuration or logging) I may give it a go. But as I understand we tested all the improvements recommended by you and they only confirmed that something is wrong without giving the precise explanation. But still, we may repeat these tests, but I would need some source code input from you.
Ad.3. Finally, maybe it is worth trying to compare to version 1.15.0 or 2.3.1 of Java TF API, so right now the legacy version, but since last month only. Maybe these versions were working somehow differently? At least I got messages, that to make it working on my GPU compute compatibility 7.0 I would have to build this API from sources, as there was some issue with PTX files or something like this and only the most recent compute capabilities were supported by default. So maybe this is some clue?

Have you looked at Python TF client to see how it uses the c++ library and what are the differences

One major difference is that the TensorFlow runtime has this thin ABI layer called "C API" which should be used by language binding libraries like TF Java to guarantee stability between TF releases but we all know that Python bypasses this layer in many cases and access directly the internal C++ classes. So maybe the C API is creating the overhead we observe or maybe it is not exposing everything that we need to enable GPU computation properly.

Finally, maybe it is worth trying to compare to version 1.15.0 or 2.3.1 of Java TF API

I completely agree, that would be an interesting test to do. The legacy version of TF Java is also calling exclusively the C API but the linkage is done differently (legacy version have custom JNI code to bind to the runtime library while the new version uses auto-generated JNI bindings using JavaCPP).
I don't expect the performances to be that different between the two versions but if they are, it will be much simpler to drill down to the actual cause of the problem.
On another note, the example from @zaleslaw shown that GPU is effectively supported by the new TF Java, and once the model has been build and ran in the C++ runtime, there is no interaction with the JVM that could impact the performances. So for now my suspicions are that:

Most of the time in your example is spent before or after running the graph (in the C API maybe?)
The graph session is not initialized properly (e.g. Python could use an internal tweak to enable more GPU kernels)

Karl

It my case, it was because I use libtensorflow_jni.so of outdated version. While it stills runs without error, GPU utilization percentage is very low. Not sure if this is your issue.


Let frontend use export result filenames from server

The front-end needs a filename to store the export result (ZIP files) it downloads from the conversion service. The conversion service already generates a (somewhat) useful filename.

let the service communicate the filename alongside the file content in a HTTP compliant way:

[ ] optional: let the URL end with the filename
[ ] make sure the HTTP headers include the filename according to RFC 6266 Section 4.3

use those informations in the front-end for storing the downloads (and for serving them to users)

[ ] get the filename according to RFC 6266 Section 4.3

beware of the different variants (unquoted token, quoted string (which may contain whitespace and quoted single characters), filename, filename*)
[ ] sanitize the filename according to RFC 6266 Section 7
[ ] optional: fallback to last part of URL
[ ] locally-generated fallback in case all of the above fail

I've asked on Software Recommendations Stack Exchange about the client (front-end) part of this: Python library to get filename of content downloaded with HTTP

This issue has been solved using other means (no more direct download through Django).


How to make a "serverless" fusion app with the stripping of node.js?

Type of issue
Feature request
Description
I find that the current version of fusion.js is merely made for React SSR app, that I can only access the entry point by some hidden logic under fusion-cli's entry file. As u illustrated in code of  L29 it is designed for some FUSION_ENTRY_PATH entry, which is also used by node hot server.
Here, I got one situation that only require the bundled React logic(for some jssdk). Is that possible to integrate the fusion independent of fusion-cli? That is
Current behavior
import App from 'fusion-react';
import Router from 'fusion-plugin-react-router';

const app = new App(root);
app.register(Router);
// I add this line: https://github.com/fusionjs/fusion-cli/blob/master/entries/client-entry.js#L29
app.callback().call();

Expected behavior
 // Could I shorten the calling process to this in my sdk?
 const app = new App(root);
 app.register(Router);

Thank you for filing a bug report. I think this is possible today, but also quite hacky. You can construct a HTML file and pull in the .fusion/ generated scripts manually. I think we would need to do a lot of work to fully support applications without a server, but it could be possible with time.
Curious about your usecase, why don't you want to use a server?

@KevinGrandon Currently, the server api is provided solely by some Java server, and we put the static javascript file and some HTMLs in nginx static server

Going to close this as a duplicate of https://github.com/fusionjs/fusion-cli/issues/484.


Could wall connector card display vehicle name

Checklist

[X] I have filled out the template to the best of my ability.
[X] This only contains 1 feature request (if you have multiple feature requests, open one feature request for each feature request).
[X] This issue is not a duplicate feature request of previous feature requests.

Is your feature request related to a problem? Please describe.
Currently Wall Connector integration shows the VIN of the connected vehicle.

Describe the solution you'd like
Could it also show the vehicle display_name aka Tesla App please?

Additional context
No response

Its an interesting idea that is technically possible but rather difficult with how the integration is structured. Ill put this on the backlog for when I want a challenge.

Wall connector device is now showing vehicle names, thanks!


Use anyhow for prettier errors on the console

Since this application does not have a GUI at the moment but has a comparatively wide target audience, some clearer error message such as those provided by anyhow instead of the default output of panics on Result::unwrap (like in #33) might be helpful for users to figure out their issues more quickly (on their own).
Just an idea I'm putting up here.
Also, implementing proper bubbling of Errs until the main method will also be beneficial when a GUI is eventually added.

related https://github.com/IceDynamix/reliquary/pull/3

Ah, I didn't even notice there was a separate library project. Indeed, reliquary should be using thiserror, whereas anyhow makes more sense for reliquary-archiver as the user-facing component.


[BUG] client.hashtag_related_hashtags(name: str) raises ClientLoginRequired due to JSONDecodeError

Compensate with donations ($10 and more) for the time I spent to fix problems or send  me your Pull Request with fixes

Bitcoin: 3KHgnvNNWio6wyQ71cgNeBQojXStxzkzfd
Ethereum: 0x6e644c6b975B47801072b07a9a57DDfEC10DE74F
https://paypal.me/adw0rd
For Russia: СБП, Qiwi и тп: +79118107609

Describe the bug
A clear and concise description of what the bug is.
After the client is ready to use (loginned with user/pass and/or cookies with settings properly configured),
calling client.hashtag_related_hashtags("art") raises ClientLoginRequired due to JSONDecodeError.
I have tracked down the code, and figured that the exception is being raised in PublicRequestMixin._send_public_request;
the exception is being called by the requests module when the code tries to run response.json() in line 132.
To Reproduce
Provide a piece of code to reproduce the problem.
cl = Client()
cl.load_settings(path)
cl.login(user=user, pass=pass)
art_related_hashtags = cl.hashtag_related_hashtags("art")
Traceback
Show your full traceback so that it is clear where exactly the error occurred.
Traceback (most recent call last):
File ".../python3.10/site-packages/requests/models.py", line 971, in json
return complexjson.loads(self.text, **kwargs)
File ".../python3.10/json/init.py", line 346, in loads
return _default_decoder.decode(s)
File ".../python3.10/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File ".../python3.10/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File ".../python3.10/site-packages/instagrapi/mixins/public.py", line 132, in _send_public_request
self.last_public_json = response.json()
File ".../python3.10/site-packages/requests/models.py", line 975, in json
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File ".../python3.10/site-packages/IPython/core/interactiveshell.py", line 3398, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "", line 1, in <cell line: 1>
art_related_hashtags = cl.hashtag_related_hashtags('art')
File ".../python3.10/site-packages/instagrapi/mixins/hashtag.py", line 129, in hashtag_related_hashtags
data = self.public_a1_request(f"/explore/tags/{name}/")
File ".../python3.10/site-packages/instagrapi/mixins/public.py", line 173, in public_a1_request
response = self.public_request(
File ".../python3.10/site-packages/instagrapi/mixins/public.py", line 76, in public_request
raise e  # Stop retries
File ".../python3.10/site-packages/instagrapi/mixins/public.py", line 74, in public_request
return self._send_public_request(url, **kwargs)
File ".../python3.10/site-packages/instagrapi/mixins/public.py", line 138, in _send_public_request
raise ClientLoginRequired(e, response=response)
instagrapi.exceptions.ClientLoginRequired: Expecting value: line 1 column 1 (char 0)
Expected behavior
A clear and concise description of what you expected to happen.
The only expectation I had was that some data must've been returned. But instead I got an exception. Honsetly I have no idea how this data should even be structured.
I tried reproducing it manually (because of public api), and got a 200 response, but it does not contain the expected json format.
code reproduced
r = requests.get('https://www.instagram.com/explore/tags/art/', params={'__a': 1, '__d': 'dis'}')
The output of r.text was a full html containing css and js of page https://www.instagram.com/explore/tags/art/.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):

OS: [e.g. Ubuntu 21.04] 22.04
Python version [e.g. 3.8.3] 3.10
instagrapi version [e.g. 1.9.3, not "latest"] 1.16.27
moveipy version if used
imagemagick version if used

Additional context
Add any other context about the problem here.
I tried to track down the url path of "https://www.instagram.com/explore/tags/{name}/", but I reached a dead-end since there was no trace of such a thing neither in the page itself, nor Instagram Basic Display Api, and also not in Instagram GraphQL Api.
I'm actually not sure where you got these paths from, except by sniffing the app itself.

Hi again.
I have narrowed the problem even more than before.So, here's the update.
I tried reproducing the manual request again like this:
import requests session = requests.Session() session.verify = False session.headers.update({     'Connection': 'Keep-Alive',     'Accept': '*/*',     'Accept-Encoding': 'gzip,deflate',     'Accept-Language': 'en-US',     'User-Agent': 'Instagram <IP_ADDRESS>.108 Android (30/11.0.0; 440dpi; 1080x2400; Xiaomi; Redmi Note 9 Pro; joyeuse; qcom; en_US; 314665256)',     'Authorization': client.authorization }) r = session.get("https://www.instagram.com/explore/tags/art/", params={'__a': 1, '__d': 'dis'})
and when returned, r.url did not have '/login/' in it. and r.json() did not raise any exceptions.
But when I replaced user agent with PublicRequestMixin's session.headers.update's user agent, the response behaved like I explained in my original bug report.
So I have this guess that apparently the request is using the original header set within PublicRequestMixin.init and not the one provided through settings. If that is the case, (i couldn't debug the original request sent by instagrapi) then it can be concluded that instagram public api will behave according to the user agent; if it thinks you're a phone user, it will send you json data, else otherwise.
But that is not all. When I looked into the fixed request, there was a lot of data. I didn't know where to look, so I traced the code. It seems like even if the user-agent problem is fixed, still the code will raise an exception. And that is KeyError: graphql which will be raised in PublicRequestMixin.public_a1_request.
Now, here's a wild insight. Despite me not knowing what processes actually went into designing this method, I have a guess. You see, I did a little research on instagram related hashtags, and this article had section called Use Instagram’s Related Hashtags feature. In there I saw a picture that showed that whilst seeing a hashtags top medias, there also are related hashtags presented to the app user. Take note that this article was from July, 19, 2022. But when I looked at my own phone, I did not find anything related. So my wild guess is that maybe instagram has removed this feature. Or... My user agent (meaning my phone model) is being discriminated against by instagram (haha). IDK.


feat(*): add from and repo for dependency resolve

This addresses #209 and #213, and adds ability to constrain
dependencies based on repo, not just name and version.

One problem I forsee is the need to normalize the repo representation, since the repo URI can vary depending on protocols. For example, these should be equivalent:

https://github.com/gabrtv/charts(.git)?
git://github.com/gabrtv/charts(.git)?
git+ssh://github.com/gabrtv/charts(.git)?

.. all should map to github.com/gabrtv/charts.  Anyway, that's a separate issue. This LGTM!

Added repo name normalization as suggested by @gabrtv.

Do from: and repo: need some docs, or does this close #209 and #213?

I should probably add something explaining how these get generated and what they're used for.

@mboersma would you mind doing a quick review of the docs on this one? It's only a few paragraphs. But I don't want to merge without at least one person eyeballing my changes.

Docs LGTM.


How to override the unhandled.xsl match="*" template

I might be missing something obvious but I'm trying to add an override to the match="*" template in unhandled.xsl to have it not terminate but instead write out the illegal elements as html.
I have tried both xsl:import and xsl:include of my custom-unhandled.xsl in my root customization, and also tried specifying the template directly in the root customization, with and without specifying the mode m:docbook.
As soon as I do however, it matches all docbook elements and outputs them as "unhandled".
Any advice on how to get this to work?

That is quite the conundrum. Yuck. I can't think of a workaround off the top of my head. I think the straightforward solution is to add a boolean flag to control whether it should be a fatal error or not.

Thanks for confirming.
A parameter would help but I wonder if a new mode that is called from the template could offer more customization options? I.e mode="m:unhadled"?

Yes, that's a good idea.


Uncaught TypeError: Cannot read property 'ease' of undefined

hey,
On line 18 you are trying to access ease in opts, but it has no default value.

Whoops! Fixed in 2.0.3


[TransferWise] Add feedback after paying expense

Confirm that the transfer was created and explain what the expense status "Processing" means.

Maybe we should also include that in the host dashboard / expense admin actions redesign (see #2896, ping @piamancini)


Make error while cross-compiling

Hi All,
I am facing an issue while running make. camke ../. is successfully generating the build files. But when I run make I get below errors:
/opt/poky/3.1.12/sysroots/x86_64-pokysdk-linux/usr/bin/cmake -S/root/sources/aws-iot-client -B/root/sources/aws-iot-client/build --check-build-system CMakeFiles/Makefile.cmake 0
/opt/poky/3.1.12/sysroots/x86_64-pokysdk-linux/usr/bin/cmake -E cmake_progress_start /root/sources/aws-iot-client/build/CMakeFiles /root/sources/aws-iot-client/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/root/sources/aws-iot-client/build'
make -f lib/aws-iot-device-sdk-cpp/CMakeFiles/aws-iot-sdk-cpp.dir/build.make lib/aws-iot-device-sdk-cpp/CMakeFiles/aws-iot-sdk-cpp.dir/depend
make[2]: Entering directory '/root/sources/aws-iot-client/build'
cd /root/sources/aws-iot-client/build && /opt/poky/3.1.12/sysroots/x86_64-pokysdk-linux/usr/bin/cmake -E cmake_depends "Unix Makefiles" /root/sources/aws-iot-client /root/sources/aws-iot-client/lib/aws-iot-device-sdk-cpp /root/sources/aws-iot-client/build /root/sources/aws-iot-client/build/lib/aws-iot-device-sdk-cpp /root/sources/aws-iot-client/build/lib/aws-iot-device-sdk-cpp/CMakeFiles/aws-iot-sdk-cpp.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/root/sources/aws-iot-client/build'
make -f lib/aws-iot-device-sdk-cpp/CMakeFiles/aws-iot-sdk-cpp.dir/build.make lib/aws-iot-device-sdk-cpp/CMakeFiles/aws-iot-sdk-cpp.dir/build
make[2]: Entering directory '/root/sources/aws-iot-client/build'
[  1%] Building CXX object lib/aws-iot-device-sdk-cpp/CMakeFiles/aws-iot-sdk-cpp.dir/src/Action.cpp.o
cd /root/sources/aws-iot-client/build/lib/aws-iot-device-sdk-cpp && /opt/poky/3.1.12/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-g++   -mthumb -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -fstack-protector-strong  -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi --sysroot=/opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi  -DOPENSSL_LOAD_CONF -DSDK_VERSION_STRING="1.4.0" -I/root/sources/aws-iot-client/build/third_party/rapidjson/src/include -I/root/sources/aws-iot-client/lib/aws-iot-device-sdk-cpp/include  -O2 -pipe -g -feliminate-unused-debug-types  -fPIC   -pthread -std=c++11 -o CMakeFiles/aws-iot-sdk-cpp.dir/src/Action.cpp.o -c /root/sources/aws-iot-client/lib/aws-iot-device-sdk-cpp/src/Action.cpp
cc1plus: warning: include location "/usr/include/x86_64-linux-gnu" is unsafe for cross-compilation [-Wpoison-system-directories]
In file included from /opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/wchar.h:30,
from /opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/c++/9.3.0/cwchar:44,
from /opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/c++/9.3.0/bits/postypes.h:40,
from /opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/c++/9.3.0/bits/char_traits.h:40,
from /opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/c++/9.3.0/string:40,
from /root/sources/aws-iot-client/lib/aws-iot-device-sdk-cpp/include/Action.hpp:27,
from /root/sources/aws-iot-client/lib/aws-iot-device-sdk-cpp/src/Action.cpp:26:
/usr/include/x86_64-linux-gnu/bits/floatn.h:75:70: error: unknown machine mode 'TC'
75 | typedef _Complex float __cfloat128 attribute ((mode (TC)));
|                                                                      ^
/usr/include/x86_64-linux-gnu/bits/floatn.h:87:9: error: '__float128' does not name a type; did you mean '__cfloat128'?
87 | typedef __float128 _Float128;
|         ^~~~~~~~~~
|         __cfloat128
In file included from /opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/c++/9.3.0/cwchar:44,
from /opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/c++/9.3.0/bits/postypes.h:40,
from /opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/c++/9.3.0/bits/char_traits.h:40,
from /opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/c++/9.3.0/string:40,
from /root/sources/aws-iot-client/lib/aws-iot-device-sdk-cpp/include/Action.hpp:27,
from /root/sources/aws-iot-client/lib/aws-iot-device-sdk-cpp/src/Action.cpp:26:
/opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/wchar.h:406:8: error: '_Float128' does not name a type; did you mean '_Float32x'?
406 | extern _Float128 wcstof128 (const wchar_t *__restrict __nptr,
|        ^~~~~~~~~
|        _Float32x
/opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/wchar.h:523:8: error: '_Float128' does not name a type; did you mean '_Float32x'?
523 | extern _Float128 wcstof128_l (const wchar_t *__restrict __nptr,
|        ^~~~~~~~~
|        _Float32x
In file included from /opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/c++/9.3.0/cstdlib:75,
from /opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/c++/9.3.0/ext/string_conversions.h:41,
from /opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/c++/9.3.0/bits/basic_string.h:6493,
from /opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/c++/9.3.0/string:55,
from /root/sources/aws-iot-client/lib/aws-iot-device-sdk-cpp/include/Action.hpp:27,
from /root/sources/aws-iot-client/lib/aws-iot-device-sdk-cpp/src/Action.cpp:26:
/opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/stdlib.h:152:8: error: '_Float128' does not name a type; did you mean '_Float32x'?
152 | extern _Float128 strtof128 (const char *__restrict __nptr,
|        ^~~~~~~~~
|        _Float32x
/opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/stdlib.h:245:4: error: '_Float128' has not been declared
245 |    _Float128 __f)
|    ^~~~~~~~~
/opt/poky/3.1.12/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/include/stdlib.h:330:8: error: '_Float128' does not name a type; did you mean '_Float32x'?
330 | extern _Float128 strtof128_l (const char *__restrict __nptr,
|        ^~~~~~~~~
|        _Float32x
make[2]: *** [lib/aws-iot-device-sdk-cpp/CMakeFiles/aws-iot-sdk-cpp.dir/build.make:63: lib/aws-iot-device-sdk-cpp/CMakeFiles/aws-iot-sdk-cpp.dir/src/Action.cpp.o] Error 1
make[2]: Leaving directory '/root/sources/aws-iot-client/build'
make[1]: *** [CMakeFiles/Makefile2:338: lib/aws-iot-device-sdk-cpp/CMakeFiles/aws-iot-sdk-cpp.dir/all] Error 2
make[1]: Leaving directory '/root/sources/aws-iot-client/build'
make: *** [Makefile:130: all] Error 2
I don't understand why do I get such errors.
And also why there is a warning cc1plus: warning: include location "/usr/include/x86_64-linux-gnu" is unsafe for cross-compilation [-Wpoison-system-directories]? I expected it to include libraries and binaries from cross-compiler toolchain.
And also, do I need to modify ToolchainFile.cmake ? I am building this on a Ubuntu 20.04 machine and my target is STM32MP157 based Avcenger96 board. I have already built and installed toolchain and sourced the environment file before building aws-iot-client.
Can someone please let me know how to resolve these issues?
Your help will be much appreciated.

Sorry, but I don't have any suggestions other than to try to use this with the v2 sdk. There is nothing that stands out in your error logs and I have no way of reproducing on your target board.
As for your second and third questions, it does look like you will need to edit the ToolchainFile.cmake. This stackoverfow question might help you with that


feat: differentiable PyTorch backend

Feature
An alternative and fully differentiable backend of norbert for PyTorch users. One extra dimension is required for input Tensors to make it be able to process in batch, which comes in handy for deep learning training. This implementation had been used to train Danna-Sep [^danna][^mdx]. This change is backward compatible so it won't affect any existing projects that depend on norbert.
Usage
To use the PyTorch backend, users can simply just replace each call of norbert.* into norbert.torch.*.
Available Functions

expectation_maximization
wiener
softmask
wiener_gain
apply_filter
get_mix_model
get_local_gaussian_model
residual_model
reduce_interferences

Note
In order to make the new backend differentiable, some in-place operations in the original code were re-written so it's not a simple one-to-one translation.
BTW, I have some problems building the docs so I'm not sure what the documentation will be like after this PR. If anyone could help me check the docs I'll appreciate it.
[^mdx]: Yuki et al.  "Music Demixing Challenge 2021". https://doi.org/10.3389/frsip.2021.808395
[^danna]: Yu, Chin-Yun, and Kin-Wai Cheuk. "Danna-Sep: Unite to separate them all". https://arxiv.org/abs/2112.03752

@yoyololicon thats great 🙌  Have you seen our implementation in https://github.com/sigsep/open-unmix-pytorch/blob/master/openunmix/filtering.py ?

Is yours using complex or real dtypes?
can you benchmark against the one in openunmix?
did you make sure the numpy and torch outputs are identical (with a margin of error)? I don't see such a regression test in this PR

@faroit

Have you seen our implementation in https://github.com/sigsep/open-unmix-pytorch/blob/master/openunmix/filtering.py ?

Thanks for the info, I haven't checked this one before.

Is yours using complex or real dtypes?

Did you mean using PyTorch native complex type? Yes.

can you benchmark against the one in openunmix?

Sure. I think we can also profile the memory usage as well.

did you make sure the numpy and torch outputs are identical (with a margin of error)? I don't see such a regression test in this PR

As I can remember, we haven't directly compared them before. I agree we should add a regression test and report the numbers.

Thanks a lot, that's great !! I remember talking to you about doing a PR for norbert, that's fantastic you took time to do it.
If you could indeed do the few tests @faroit mentions, that would be perfect
Does your implementation allow backprop even with a number of iterations > 0 ?
best

Thanks a lot, that's great !! I remember talking to you about doing a PR for norbert, that's fantastic you took time to do it.

@aliutkus Yeah, I remember it, too. 😄

If you could indeed do the few tests @faroit mentions, that would be perfect Does your implementation allow backprop even with a number of iterations > 0 ?

Theoretically, it can backprop any number of iterations, but we always set it to one iteration in our training.
I'll add the tests later.

@faroit @aliutkus I added the regression tests and should be ready for review.
See below for the benchmarks.

It's always 2 to 3 times faster than openunmix.
[----------------- wiener -----------------]
              |  norbert torch  |  openunmix
1 threads: ---------------------------------
      [4, 0]  |        4.2      |      6.7
      [4, 1]  |       46.8      |     80.6
      [4, 3]  |      130.4      |    233.0
      [8, 0]  |        4.0      |      8.2
      [8, 1]  |       84.0      |    167.4
      [8, 3]  |      232.6      |    470.5
2 threads: ---------------------------------
      [4, 0]  |        2.2      |      3.7
      [4, 1]  |       24.9      |     48.8
      [4, 3]  |       70.5      |    138.0
      [8, 0]  |        2.3      |      4.7
      [8, 1]  |       46.9      |     97.8
      [8, 3]  |      126.4      |    294.0
4 threads: ---------------------------------
      [4, 0]  |        1.2      |      2.3
      [4, 1]  |       16.0      |     38.3
      [4, 3]  |       41.6      |    106.2
      [8, 0]  |        1.9      |      3.5
      [8, 1]  |       29.6      |     82.3
      [8, 3]  |       80.6      |    226.7

Times are in milliseconds (ms).

The script I used to produce those experiments
import torch
from torch.profiler import profile, record_function, ProfilerActivity
import torch.utils.benchmark as benchmark
from itertools import product

import norbert.torch as norbert
from openunmix import filtering

nb_frames = 100
nb_bins = 513
nb_channels = 2
nb_sources = [4, 8]
nb_iterations = [0, 1, 3]

x = torch.randn(nb_frames, nb_bins, nb_channels) + 1j * \
    torch.randn(nb_frames, nb_bins, nb_channels)
x_as_real = torch.view_as_real(x)
v = torch.rand(nb_frames, nb_bins, nb_channels, 4)

with profile(activities=[ProfilerActivity.CPU], profile_memory=True) as prof:
    norbert.wiener(v[None, ...], x[None, ...])
print("Norbert Torch")
print(prof.key_averages().table(sort_by="self_cpu_memory_usage", row_limit=5))

with profile(activities=[ProfilerActivity.CPU], profile_memory=True) as prof:
    filtering.wiener(v, x_as_real)
print("Open-Unmix")
print(prof.key_averages().table(sort_by="self_cpu_memory_usage", row_limit=5))

results = []
for ns, ni in product(nb_sources, nb_iterations):
    label = 'wiener'
    sub_label = f'[{ns}, {ni}]'
    v = torch.rand(nb_frames, nb_bins, nb_channels, ns)
    x = torch.randn(nb_frames, nb_bins, nb_channels) + 1j * \
        torch.randn(nb_frames, nb_bins, nb_channels)
    x_as_real = torch.view_as_real(x)

    for num_threads in [1, 2, 4]:
        results.append(benchmark.Timer(
            stmt='y = wiener(v, x, i)',
            setup='from norbert.torch import wiener',
            globals={'x': x.unsqueeze(0), 'v': v.unsqueeze(0), 'i': ni},
            label=label,
            num_threads=num_threads,
            sub_label=sub_label,
            description='norbert torch',
        ).blocked_autorange(min_run_time=1))

        results.append(benchmark.Timer(
            stmt='y = wiener(v, x, i)',
            setup='from openunmix.filtering import wiener',
            globals={'x': x_as_real, 'v': v, 'i': ni},
            label=label,
            num_threads=num_threads,
            sub_label=sub_label,
            description='openunmix',
        ).blocked_autorange(min_run_time=1))

compare = benchmark.Compare(results)
compare.print()

@yoyololicon sorry for the slow response. I will have a look next week 🙏

This looks great, @faroit would be amazing to be able to pip install this

@yoyololicon Totally forgot about this one. I will have a look again

@faroit No problem. Take your time. Let's first enjoy the ISMIR conference 😆


Impossible to get a 0 to 100 display with values between 0 and 1 mapped as "Percentage"

Hi there,
I love this plugin but since the last update (or may be a previous one), I cannot have the display as expected:

The values getted from Els are between 0 and 1 and represents percentage,
Those values are mapped to percentage type so they are correctly displayed in "Discovery" like 0 to 100 values (and not 0 to 1).

Now I want to display a gauge with:

green between 0 to 50 %,
yellow between 50% to 80 %,
red if above 80%

My setting was the following (before update):
gauge min: 0,
gauge max: 1,
gauve level1: 0, Green,
gauve level2: 50, Yellow
gauve level3: 80, Red
But the displayed value is always not percentage formatted (ie 0,05 % instead of 5 %) and the color didn't change at the threshold I gave.
Any clues for what happens ?

I update plugin for your issue and add size option...

Fixed by commit https://github.com/sbeyn/kibana-plugin-gauge-sg/commit/eaa3a00e233fbc15d7a88d1685766b4074f9c97a
I will check this ASAP and keep you in touch.

Hello again,
I test the patch but it's better but not totally ok:

with Min=0, Max=1, level1=50, ... level4=95, the number displayed is OK but all gaude is red (ie >=95%).

with Min=0, Max=1, level1=.5, ..., level4=.95, the color is green (yellow expected) and the value is 0.81% (80% expected).

So I'm stuck with configuration of the plugin once more.
My value is a number value (0.8) formatted as Percent value (to have 80% and not 0.8)

I try to remove the Percent formatting value but it have not effect on the way the Gauge is displayed

For information, I'm on the 4.x branch.

Looking at code, it seems that bug is at lien 60 of gauge_sg_controller.js. The line should be :
metrics[0] = { label: table.columns[nbr_c - 1].title, value: sum / nbr_r * 100 };
Note: I remove  / $scope.vis.params.maxGauge which leads to 0.84 instead of 84

I can confirm than this fix fixes the bug. I've made a local modification to test the proposed modification.


Incorrect frame data on jin ws2

Jins ws2 has incorrect frame data on block unless you hit them when getting up off the ground
https://i.imgur.com/5WnKAs7.mp4

See #13.


release-please-action not tagging releases after manifest-pr is merged

TL;DR
Here is an implementation of creating a release PR: https://github.com/ipfs/ipfs-companion/blob/main/.github/workflows/ci.yml#L96-L104
This creates the release PR as expected. On merging this PR, this action runs again, but does nothing. The expectation is not to create a release, because the need is to add more assets to the created release. The release step is separate and is executed when a new tag gets pushed. However release-please-action does not push the tag hence this step never gets executed.
Expected behavior
Since release-please-action is only being used to create a collector PR and not the release itself, the expectation as per the documentation was:

When you're ready to tag a release, simply merge the release PR.

This does not happen if the release step is not happening.
Observed behavior
The release PR merges without creating a release tag, breaking the workflow.
Action YAML
release-pr:
    runs-on: ubuntu-latest
    needs: [test]
    if: github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
    steps:
      - uses<EMAIL_ADDRESS>        with:
          command: manifest-pr
          changelog-notes-type: github

Log output
No response
Additional information
No response

If you want it to tag, use the manifest command. The manifest-pr command only creates the PR (manifest does PR creation and tagging)


remove geemap dependency

geemap pulls in an awful lot of dependencies. currently we use it only in the sentinel-2 download and preformat files:

src\thaw_slump_segmentation\scripts\download_s2_4band_planet_format.py
src\thaw_slump_segmentation\scripts\prepare_s2_4band_planet_format.py

which are as far as i can see superseded as this is done in thaw-slump-segmentation-pipeline and in branch sentinel2_native.
we should remove the geemap dependency once sentinel2 is stable to make packaging easier. if necessary functionality can be reproduced, as we use only download capabilities (uses geedim anyway) and data conversion from and to GeoDataFrame.

    df = ee.data.computeFeatures({
        'expression': ftrCollection,
        'fileFormat': 'GEOPANDAS_GEODATAFRAME'
    })

partially completed with #152


docs: CoreAvatarGroup component issue in valid props

Describe the bug
Buggy table content of its valid props, related to #97

[x] Extra row in spacing prop

[x] Buggy table row in variant prop

Additional context

Documentation URLs:

http://<IP_ADDRESS>:xxxx/guide/components

Note: Ensure that the placeholders xxxx are replaced with the hosted port number.

Done and merged


Update fibonacci to use temporary variables and local variables

https://www.cairo-lang.org/docs/how_cairo_works/consts.html#temporary-variables
https://www.cairo-lang.org/docs/how_cairo_works/consts.html#local-variables

@HermanObst please check this

This issue seems to have been fixed in commit<PHONE_NUMBER>e076fc439634f7802d3f25a669a1c6
Are we good to close it?


Problem with the function scrape_location

Hello
When I run the program, I can add a location to the database but when I try to run the function "scrape_location" for scraping media, it raises a KeyError with prefixURL since yesterday.
Can you help me fixing this?
Thanks!!

In "def scrape_location" try to use :
media = info.get('streamingMediaInfo')
thumbnail = info.get('streamingThumbnailInfo')
preview_url = None
media_url = None
overlay_url = None
if media:
if media.get('mediaUrl'):
media_url = media['mediaUrl']
if media.get('overlayUrl'):
overlay_url = media['overlayUrl']
if not overlay_url.endswith('png'):
print(f'Overlay url: {overlay_url}')
if thumbnail:
preview_url = thumbnail['infos'][0]['thumbnailUrl']

Hi @ili403, thank you for mentioning this! I've pushed a new change that should fix this. Please download the code again or run git pull to get the latest.


store: Enhance zookeeper lock with value support

Add support for setting values in zookeeper lock.
This is pretty much all we need for leader election as go-zookeeper already has support for locks.
Signed-off-by: Alexandre Beslic<EMAIL_ADDRESS>

LGTM with minor comment

@aluzzardi PTAL


Social Post: Install Time Improvements

Related Issue
Title:
Installing FlowFuse just got 3x faster
before: 555s
after: 166s
Description
Considerations:

Social Post

Inspirations:

https://github.com/FlowFuse/flowfuse/issues/4573#issuecomment-2455185388

Want to shout about how we've made improvements in the onboarding/installing time, @ZJvandeWeg mentioned we could do a single graphic to do a social post
Clear "before"/after is the message that needs communicating, could do a vertical Sankey diagram type image?

Hi @joepavitt
is this something like what you had in mind?

It is, although I think the title needs to be brighter, and the 555/166 can be written as Xm Ys instead to make it easier to read - maybe even a little larger too?

And for the description:

🚀 Installing FlowFuse just got 3x faster!
Our latest update has reduced installation times, cutting them down from over 9 minutes to under 3 minutes. This means you can start working with FlowFuse without delays and with a much smoother setup process.
Interested in giving it a try? Check out the complete installation guide to set up FlowFuse in your Docker environment and get started in minutes.
🔗 https://flowfuse.com/docs/install/docker/
#FlowFuse #NodeRED #IIoT #Automation #Docker

WDYT?

you can start working with Self-Hosted FlowFuse with

Added in "Self Hosted", just to stress that this is for self-hosted installs. FF Cloud getting started times is seconds

Done. I've scheduled it for tomorrow.


Argument hints

Hi,
First of all I want to thank you, @marijnh, for a fantastic job with ternJS, it's awesome (and I can't wait for ES6 support, I will gladly fund it).
However, I have some problem to get argument hints for function call, see my gif:

Do I miss something?
My Preferences.sublime-settings contains the following lines:
"tern_command": [
    "/usr/local/bin/node",
    "/absoult_path_to/Packages/tern_for_sublime/node_modules/tern/bin/tern"
],
"tern_argument_hints": true,

My .tern-project:
{
  "plugins": {
    "doc_comment": {
      "fullDocs": true
    }
  }
}

In brackets I get the following (expected) result:

Your setting looks entirely correct, and given the fact that you are getting proper completions, I can't explain why the argment hints are not showing up. Maybe try adding debug output (Python print statements will end up in the ctrl-~ console) to the plugin code, to see whether arghints_enabled ends up being set to True, and whether show_argument_hints is being called, etcetera.

FWIW, argument hints are working for me.
latest ST 3 dev build
latest tern_for_sublime release
OS X 10.8

Nice, I have tried it on an other computer (build 3070) and it works like a charm. I will however wait for build 3070 to be released as non-dev-preview before I use it. I close this ticket in the meanwhile.

+1 on the problem of non-showing argument hints in both, build 3065 and 3079 despite setting tern_argument_hints

@chris-- argument hints wont appear until you're within the (..) of the function.
The screenshot provided shows the correct behavior.

@subhaze ah, i see. Apparently, it does work on dev build 3079! Thanks for the quick response.


Edit find command so that multiple tag prefixes are supported

Codecov Report

Merging #325 (8b9fb40) into master (f9aff4d) will decrease coverage by 0.12%.
The diff coverage is 46.15%.

@@             Coverage Diff              @@
##             master     #325      +/-   ##
============================================
- Coverage     54.54%   54.42%   -0.13%
- Complexity      647      649       +2
============================================
  Files           126      126
  Lines          2836     2850      +14
  Branches        365      367       +2
============================================
+ Hits           1547     1551       +4
- Misses         1163     1171       +8
- Partials        126      128       +2

Impacted Files
Coverage Δ

.../parser/personcommand/FindPersonCommandParser.java
34.69% <22.22%> (-2.52%)
:arrow_down:

...ogic/parser/taskcommand/FindTaskCommandParser.java
26.15% <22.22%> (-0.97%)
:arrow_down:

...del/person/TagPersonContainsKeywordsPredicate.java
100.00% <100.00%> (ø)

...h/model/task/TagTaskContainsKeywordsPredicate.java
100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f9aff4d...8b9fb40. Read the comment docs.


New alert

Added sweet alert for "suggesting course instead of normal alert"

Hi, thank you for the contribution. Could you attach a screenshot to this?

Basically i just changed  swal instead of normal alert in suggest a course you can find more about sweet alert in https://sweetalert.js.org/
I can't run this program because of the firebase config
i could give you a preview of sweet alert from another site


fix: rearranged ENV variables in strict 'sort' order

It started with move-mutex and then it evolved a bit (hence the branch name).

Are tables sorted in the readme*? Maybe we want to double check and sort everything...

Good thinking. Done that for both READMEs.


Filesystem changed events in AbstractStorage

The problem
Most file systems provide a way to notify when the contents of a folder is changed. However, AbstractStorage doesn't have the same thing.
The solution
Add events to IFolderData to notify when

A file is added
A file is removed

AbstractStorage is being succeeded by https://github.com/Arlodotexe/OwlCore.Storage.


fixed openVPN connection with openLDAP support

fixed VPN configuration
fixed LDAP connection
refactured bash scripts

Hi.  Aside from the refactoring of the scripts, could you tell me what this is actually fixing?

Hi. Aside from the refactoring of the scripts, could you tell me what this is actually fixing?

I tried to use the Docker image to connect to another Docker container running openLDAP for authentication. This was not functional. So I forked the current master branch and started debugging the scripts. I found some issues and fixed them. Also, I refactured the scripts for a better readaility, e.g. used correct options for "test" or sorted variable definitions.
The current pull request is operational now. Please feel free to test the changes - or reject the pull request. I just wanted to share my work with your great repo.

Hi! I can confirm that knieselpriems aproach is working for me. It would be nice to see this PR merged for one great code base. Thank you @wheelybird for your solution which helps me a lot.

@tgruenert I didn't merge this as I was never told what it's actually fixing.  All I could see were changes to coding style - I couldn't identify an actual issue being solved.  Can you tell me what problem it solved for you?

300+ line changes in a single commit with a message saying "fixed VPN, LDAP, refactured (sic) bash script", wow.
If someone in my team did this I'd remove their git access, and probably their keyboard.

after reading your good question i give the original repo a second try. indeed LDAP auth for my usecase works exactly the same way like @knieselpriem ´s one. so i can´t see any need for merge from now on.
Thank your for your solution. Will test this from now one with some colleges of mine.


Target UUID::UUID does not exist

Original report (archived issue) by Anonymous.

I have been trying to update an older ROS-Gazebo project, to gazebo 9 that is using ignition math:
https://github.com/ethz-asl/rotors_simulator
Currently I am running Ubuntu 18.04, and Gazebo 9.1 and cmake 3.10.2.
When I compile the code get an error from CMAKE, that looks like this:
CMake Error at /home/martin/ros_sim_drone/src/rotors_simulator/rotors_gazebo_plugins/CMakeLists.txt:26 (target_link_libraries):
  Error evaluating generator expression:

    $<TARGET_PROPERTY:UUID::UUID,INTERFACE_INCLUDE_DIRECTORIES>

  Target "UUID::UUID" not found.

The whole response looks like this:
Errors     << rotors_gazebo_plugins:check /home/martin/ros_sim_drone/logs/rotors_gazebo_plugins/build.check.002.log
CMake Warning (dev) at /usr/share/cmake-3.10/Modules/FindBoost.cmake:911 (if):
  Policy CMP0054 is not set: Only interpret if() arguments as variables or
  keywords when unquoted.  Run "cmake --help-policy CMP0054" for policy
  details.  Use the cmake_policy command to set the policy and suppress this
  warning.

  Quoted variables like "chrono" will no longer be dereferenced when the
  policy is set to NEW.  Since the policy is not set the OLD behavior will be
  used.
Call Stack (most recent call first):
  /usr/share/cmake-3.10/Modules/FindBoost.cmake:1558 (_Boost_MISSING_DEPENDENCIES)
  /usr/share/OGRE/cmake/modules/FindOGRE.cmake:318 (find_package)
  /usr/lib/x86_64-linux-gnu/cmake/gazebo/gazebo-config.cmake:175 (find_package)
  CMakeLists.txt:20 (find_package)
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) at CMakeLists.txt:28 (add_library):
  Policy CMP0028 is not set: Double colon in target name means ALIAS or
  IMPORTED target.  Run "cmake --help-policy CMP0028" for policy details.
  Use the cmake_policy command to set the policy and suppress this warning.

  Target "rotors_gazebo_bag_plugin" links to target "UUID::UUID" but the
  target was not found.  Perhaps a find_package() call is missing for an
  IMPORTED target, or an ALIAS target is missing?
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) at CMakeLists.txt:28 (add_library):
  Policy CMP0028 is not set: Double colon in target name means ALIAS or
  IMPORTED target.  Run "cmake --help-policy CMP0028" for policy details.
  Use the cmake_policy command to set the policy and suppress this warning.

  Target "rotors_gazebo_bag_plugin" links to target "UUID::UUID" but the
  target was not found.  Perhaps a find_package() call is missing for an
  IMPORTED target, or an ALIAS target is missing?
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Error at /home/martin/ros_sim_drone/src/rotors_simulator/rotors_gazebo_plugins/CMakeLists.txt:29 (target_link_libraries):
  Error evaluating generator expression:

    $<TARGET_PROPERTY:UUID::UUID,INTERFACE_INCLUDE_DIRECTORIES>

  Target "UUID::UUID" not found.

CMake Error:
  Error evaluating generator expression:

    $<TARGET_PROPERTY:UUID::UUID,INTERFACE_INCLUDE_DIRECTORIES>

  Target "UUID::UUID" not found.

CMake Error:
  Error evaluating generator expression:

    $<TARGET_PROPERTY:UUID::UUID,INTERFACE_INCLUDE_DIRECTORIES>

  Target "UUID::UUID" not found.

CMake Error at /home/martin/ros_sim_drone/src/rotors_simulator/rotors_gazebo_plugins/CMakeLists.txt:29 (target_link_libraries):
  Error evaluating generator expression:

    $<TARGET_PROPERTY:UUID::UUID,INTERFACE_INCLUDE_DIRECTORIES>

  Target "UUID::UUID" not found.

make: *** [cmake_check_build_system] Error 1

My cmake file currently look like this:
cmake_minimum_required(VERSION 2.8.3)
project(rotors_gazebo_plugins)

find_package(catkin REQUIRED COMPONENTS
    cmake_modules
    geometry_msgs
    mav_msgs
    rosbag
    roscpp
    gazebo_ros
    rotors_comm
    rotors_control
    std_srvs
    tf
  )

find_package(Boost REQUIRED)
find_package(Eigen3 REQUIRED)
find_package(gazebo REQUIRED)
find_package(Protobuf REQUIRED)

link_directories(${GAZEBO_LIBRARY_DIRS})
include_directories(include ${Boost_INCLUDE_DIR} ${catkin_INCLUDE_DIRS} ${Eigen3_INCLUDE_DIRS} ${GAZEBO_INCLUDE_DIRS})

#message(AUTHOR_WARNING "${GAZEBO_INCLUDE_DIRS}")

add_library(rotors_gazebo_bag_plugin SHARED src/gazebo_bag_plugin.cpp)
target_link_libraries(rotors_gazebo_bag_plugin ${catkin_LIBRARIES} ${GAZEBO_LIBRARIES})

#message(AUTHOR_WARNING "${GAZEBO_LIBRARIES}")

catkin_package(
  INCLUDE_DIRS include
  LIBRARIES ${PROJECT_NAME} rotors_gazebo_motor_model rotors_gazebo_controller_interface
  CATKIN_DEPENDS geometry_msgs mav_msgs rosbag roscpp rotors_comm rotors_control std_srvs tf
  DEPENDS EIGEN3 GAZEBO
)

Printing out my ${GAZEBO_LIBRARIES} I got this result:
BulletSoftBody;BulletDynamics;BulletCollision;LinearMath;/usr/lib/x86_64-linux-gnu/libSimTKsimbody.so;/usr/lib/x86_64-linux-gnu/libSimTKmath.so;/usr/lib/x86_64-linux-gnu/libSimTKcommon.so;/usr/lib/x86_64-linux-gnu/libblas.so;/usr/lib/x86_64-linux-gnu/liblapack.so;/usr/lib/x86_64-linux-gnu/libblas.so;pthread;rt;dl;m;/usr/lib/x86_64-linux-gnu/libgazebo.so;/usr/lib/x86_64-linux-gnu/libgazebo_client.so;/usr/lib/x86_64-linux-gnu/libgazebo_gui.so;/usr/lib/x86_64-linux-gnu/libgazebo_sensors.so;/usr/lib/x86_64-linux-gnu/libgazebo_rendering.so;/usr/lib/x86_64-linux-gnu/libgazebo_physics.so;/usr/lib/x86_64-linux-gnu/libgazebo_ode.so;/usr/lib/x86_64-linux-gnu/libgazebo_transport.so;/usr/lib/x86_64-linux-gnu/libgazebo_msgs.so;/usr/lib/x86_64-linux-gnu/libgazebo_util.so;/usr/lib/x86_64-linux-gnu/libgazebo_common.so;/usr/lib/x86_64-linux-gnu/libgazebo_gimpact.so;/usr/lib/x86_64-linux-gnu/libgazebo_opcode.so;/usr/lib/x86_64-linux-gnu/libgazebo_opende_ou.so;/usr/lib/x86_64-linux-gnu/libgazebo_ccd.so;/usr/lib/x86_64-linux-gnu/libboost_thread.so;/usr/lib/x86_64-linux-gnu/libboost_signals.so;/usr/lib/x86_64-linux-gnu/libboost_system.so;/usr/lib/x86_64-linux-gnu/libboost_filesystem.so;/usr/lib/x86_64-linux-gnu/libboost_program_options.so;/usr/lib/x86_64-linux-gnu/libboost_regex.so;/usr/lib/x86_64-linux-gnu/libboost_iostreams.so;/usr/lib/x86_64-linux-gnu/libboost_date_time.so;/usr/lib/x86_64-linux-gnu/libboost_chrono.so;/usr/lib/x86_64-linux-gnu/libboost_atomic.so;/usr/lib/x86_64-linux-gnu/libpthread.so;/usr/lib/x86_64-linux-gnu/libprotobuf.so;-lpthread;/usr/lib/x86_64-linux-gnu/libsdformat.so;ignition-math4::ignition-math4;optimized;/usr/lib/x86_64-linux-gnu/libOgreMain.so;debug;/usr/lib/x86_64-linux-gnu/libOgreMain.so;/usr/lib/x86_64-linux-gnu/libboost_thread.so;/usr/lib/x86_64-linux-gnu/libboost_date_time.so;/usr/lib/x86_64-linux-gnu/libboost_system.so;/usr/lib/x86_64-linux-gnu/libboost_atomic.so;/usr/lib/x86_64-linux-gnu/libboost_chrono.so;/usr/lib/x86_64-linux-gnu/libboost_chrono.so;/usr/lib/x86_64-linux-gnu/libpthread.so;optimized;/usr/lib/x86_64-linux-gnu/libOgreTerrain.so;debug;/usr/lib/x86_64-linux-gnu/libOgreTerrain.so;optimized;/usr/lib/x86_64-linux-gnu/libOgrePaging.so;debug;/usr/lib/x86_64-linux-gnu/libOgrePaging.so;ignition-math4::ignition-math4;ignition-transport4::ignition-transport4;ignition-msgs1::ignition-msgs1;ignition-common1::ignition-common1;ignition-fuel_tools1::ignition-fuel_tools1

Diging a bit futher I found the following lines in gazebo-config.cmake
# Find Ignition Math
find_package(ignition-math4 REQUIRED)
list(APPEND GAZEBO_INCLUDE_DIRS ${IGNITION-MATH_INCLUDE_DIRS})
list(APPEND GAZEBO_LIBRARY_DIRS ${IGNITION-MATH_LIBRARY_DIRS})
list(APPEND GAZEBO_LIBRARIES ${IGNITION-MATH_LIBRARIES})

This lead me to "ignition-math4/ignition-math4-config.cmake" where I found this line:
set(ignition-math4_LIBRARIES ignition-math4::ignition-math4)

These libray  difinitions for ignition seems to be my current problem with my projects cmake script. I am unsure how this fix it, to get the correct library links for my project.

I'm going to go ahead and close this since it's a very old ticket and I'm not sure if it's still relevant. Please feel free to reopen if you still have this problem.


For iOS, can you play a file that is not in local asset?

For iOS, can you play a file that is not in the local asset?
I tested it, and it seems that it can't be done for iOS.  For android, it is ok.

I play local files (not assets) all the time - even now, as I type this comment :)

I tested downloading the file to the device using Flutter Cache Manager and played the file using a file path returned by Flutter Cache Manager and it works well for Android but for iOS, I just could not get it to work.
I prefer playing a file cached rather than playing it remotely as there is a significant delay for iOS when playing a file remotely.  Sometimes I think flutter is more native in Android than in iOS.
There are only that few lines but yet I could not figure out what was needed for iOS and so I thought for iOS, you would have to use AudioCache to play a file downloaded to the device.  But I believe this should not be the case.
Here is the link for the test code and if you have any suggestions for me, please let me know.
Flutter cache try

I am not familiar with AudioCache. I download files directly to the device, which gives me more control over what to do with these files: when to delete them, how much space they take, etc.
I know that Android and iOs players treat the local file paths differently.  If you don't pass "isLocal" parameter to audioplayers, it may still work on Android but not on iOs.
This is the relevant part from the plugin:
isLocal ??= url.startsWith("/") ||
        url.startsWith("file://") ||
        url.substring(1).startsWith(':\\');

Check what path you pass to the player.

Hello,
When i try to play a file that has been stored internally in IOS, and after investigating, it looks like the setUrl method does not work properly. I did not dig into objective-C code since i don't have skills for that.
The path where my file is stored is like /var/mobile/Containers/Data/Application/992AF912-9085-497B-A916-422FE9E9D135/...
However it works like a charm when remote. Of course isLocal variable have been set to true.
Device : Iphone XR
IOS version : tested on 12.4 and 13

Ok guys,
After investigating i found why it doesn't worked : Looks like AVPlayer class in IOS don't like files without extension. Ensure also that the file codec is supported by AVPlayer too.

Seems this has been fixed.