I have following code for studying.
My calculate function produces unexpected results when runs on aparapi.
Is there any problem with my code, or aparapi?
Results are;
Result Num Expected
2026982348 406816880 40681688012
2026982516 406816881 40681688180
2026982594 406816882 40681688258
2026982662 406816883 40681688326
2026982830 406816884 40681688494
2026982898 406816885 40681688562
2026982966 406816886 40681688630
2026983044 406816887 40681688708
2026983212 406816888 40681688876
2026983280 406816889 40681688944
2026983338 406816890 40681689002
2026983506 406816891 40681689170
2026983584 406816892 40681689248
2026983652 406816893 40681689316
2026983820 406816894 40681689484
2026983888 406816895 40681689552
2026983956 406816896 40681689620
2026984134 406816897 40681689798
2026984202 406816898 40681689866
2026984270 406816899 40681689934
Edit: If I set executionMode JTP or CPU, I get true results (result == expected) but on GPU mode there is a problem. I'm using late 2013 macbook pro retina with windows 10.
Edit2: Return line of my calculate method causes the problem. If I return Long.MAX_VALUE, it works. But (long) tc * 100 (or ((long) tc) * 100) not giving (eg. 40681688900)
I think you should review your code checking against Aparapi Java Kernel Guidelines, expecially paying attention to Other restrictions and Beware Of Side Effects sections.
Remember to keep your code as simpler as you can.
Looking to your code, in the calculate method you make wide use of the modulus (%) operator. I would suggest you to log each calculation in order to be able to compare what you get in JTP mode and what you get in GPU mode, in order to find out if there are some issues with this operator.
EDIT:
In your calculate method you use int variables to hold values, which may hold numbers till 2^31-1, namely 2147483647 as known as Integer.MAX_VALUE.
If you perform int value=2147483647; value++; you will get as a result -2147483648 as known as Integer.MIN_VALUE.
You can alternatively try your program with lower starting numbers or change your variable declarations to long, which may hold Long.MAX_VALUE, namely 2^63-1.
Both long and int values are supported by Aparapi.
Hi I'm the primary maintainer over at the new Aparapi.com and new github repository. We are much more active over at the new project home and even have about a dozen releases in maven central already. You might want to consider moving over to the new Aparapi.
With that said I am a developer at the new Aparapi and ran this test case and confirmed it is a legitimate Aparapi bug. I will look into what is causing the bug and hopefully can get a bug fix in for you before the next release. The issue has been reported here if you would like to track it. Remember this for the new Aparapi project so the bug fix is not likely to show up in the older Aparapi project.
Related
I know if I run a program, it will likely express one way or another: what it is expecting from each variable. But I would like to determine on my own when I read over each page of Android code etc. e.g:
How could I determine what size or length an android program is expecting a string array to be?
Whether an integer or double, is expected to be positive or negative?
etc.
Help in this regard would be much appreciated.
You can set breakpoints in your code and examine all of the variables when the program pauses. This would give you a general idea of whether the integers were positive or negative, the length and content of the strings, etc. It could be useful if the code was poorly documented.
Assuming you are using Android Studio you can follow this guide:
https://developer.android.com/tools/debugging/debugging-studio.html
for some reason I found myself coding some piece of software, that should be able to perfom some astronomic calculations.
While most of it will be about transfering the correct formula into Java, I found an annoying Problem right at the verry beginning of my "test how to calculate big numbers".
Well... Imagine the Sun (our Sun), which has a mass of (about and rounded, for more easy explaining) 10E30 kg. Ten with 30 following Zeros. All native datatypes are just unusuable for this. To mention: I KNOW that I could use 3000 to calculate things and just add trailing zeros in the output-view, but I hoped to keep it as precise as possible. So using short numbers will be my last resort only.
Comming to the Problem. Please have a look at the code:
BigDecimal combinedMass = new BigDecimal(1E22);
int massDistribution = 10;
Integer mD1 = massDistribution;
Integer mD2 = 100 - massDistribution;
BigDecimal starMass;
BigDecimal systemMass;
systemMass = combinedMass.divide(new BigDecimal("100")).multiply(new BigDecimal(mD1.toString()));
starMass = combinedMass.divide(new BigDecimal("100")).multiply(new BigDecimal(mD2.toString()));
System.out.println((systemMass).toEngineeringString());
System.out.println((starMass));
It will output 1000000000000000000000 and 9000000000000000000000, whats exactly what I did expect. But look at the combineMass Field. If I raise it to 1E23, the Output will change
I get 9999999999999999161139.20 and 89999999999999992450252.80...
So I know I could use jut BigInteger, because its more reliable in this case, but for the sake of precicion, sometimes the BigWhatEver may drop to something like 50.1258
Plus, I hope to get the 10.xE30 as output, whats only possible using bigDecimals.
I want to know: Is there no way avoidng this (that error appers above 1E23 for every value I tried), while keeping the ability to calculate Floating-Points? Should I cut the After-Decimal-Separator-Values for this Field to two digets?
And for something more to wonder about:
System.out.println(combinedMass.precision());
in relation with the code above will provide 23 for that case, but En+1 for most other values (Thats was when I grow really confused)
Thanks for advise.
You're using basic types without realizing it:
new BigDecimal(1E22);
Here, 1E22 is a primitive double, and you already lost precision by using it.
What you want is
new BigDecimal("10000000000000000000000");
or
new BigDecimal(10).pow(22);
I saw the following code in this commit for MongoDB's Java Connection driver, and it appears at first to be a joke of some sort. What does the following code do?
if (!((_ok) ? true : (Math.random() > 0.1))) {
return res;
}
(EDIT: the code has been updated since posting this question)
After inspecting the history of that line, my main conclusion is that there has been some incompetent programming at work.
That line is gratuitously convoluted. The general form
a? true : b
for boolean a, b is equivalent to the simple
a || b
The surrounding negation and excessive parentheses convolute things further. Keeping in mind De Morgan's laws it is a trivial observation that this piece of code amounts to
if (!_ok && Math.random() <= 0.1)
return res;
The commit that originally introduced this logic had
if (_ok == true) {
_logger.log( Level.WARNING , "Server seen down: " + _addr, e );
} else if (Math.random() < 0.1) {
_logger.log( Level.WARNING , "Server seen down: " + _addr );
}
—another example of incompetent coding, but notice the reversed logic: here the event is logged if either _ok or in 10% of other cases, whereas the code in 2. returns 10% of the times and logs 90% of the times. So the later commit ruined not only clarity, but correctness itself.
I think in the code you have posted we can actually see how the author intended to transform the original if-then somehow literally into its negation required for the early return condition. But then he messed up and inserted an effective "double negative" by reversing the inequality sign.
Coding style issues aside, stochastic logging is quite a dubious practice all by itself, especially since the log entry does not document its own peculiar behavior. The intention is, obviously, reducing restatements of the same fact: that the server is currently down. The appropriate solution is to log only changes of the server state, and not each its observation, let alone a random selection of 10% such observations. Yes, that takes just a little bit more effort, so let's see some.
I can only hope that all this evidence of incompetence, accumulated from inspecting just three lines of code, does not speak fairly of the project as a whole, and that this piece of work will be cleaned up ASAP.
https://github.com/mongodb/mongo-java-driver/commit/d51b3648a8e1bf1a7b7886b7ceb343064c9e2225#commitcomment-3315694
11 hours ago by gareth-rees:
Presumably the idea is to log only about 1/10 of the server failures (and so avoid massively spamming the log), without incurring the cost of maintaining a counter or timer. (But surely maintaining a timer would be affordable?)
Add a class member initialized to negative 1:
private int logit = -1;
In the try block, make the test:
if( !ok && (logit = (logit + 1 ) % 10) == 0 ) { //log error
This always logs the first error, then every tenth subsequent error. Logical operators "short-circuit", so logit only gets incremented on an actual error.
If you want the first and tenth of all errors, regardless of the connection, make logit class static instead of a a member.
As had been noted this should be thread safe:
private synchronized int getLogit() {
return (logit = (logit + 1 ) % 10);
}
In the try block, make the test:
if( !ok && getLogit() == 0 ) { //log error
Note: I don't think throwing out 90% of the errors is a good idea.
I have seen this kind of thing before.
There was a piece of code that could answer certain 'questions' that came from another 'black box' piece of code. In the case it could not answer them, it would forward them to another piece of 'black box' code that was really slow.
So sometimes previously unseen new 'questions' would show up, and they would show up in a batch, like 100 of them in a row.
The programmer was happy with how the program was working, but he wanted some way of maybe improving the software in the future, if possible new questions were discovered.
So, the solution was to log unknown questions, but as it turned out, there were 1000's of different ones. The logs got too big, and there was no benefit of speeding these up, since they had no obvious answers. But every once in a while, a batch of questions would show up that could be answered.
Since the logs were getting too big, and the logging was getting in the way of logging the real important things he got to this solution:
Only log a random 5%, this will clean up the logs, whilst in the long run still showing what questions/answers could be added.
So, if an unknown event occurred, in a random amount of these cases, it would be logged.
I think this is similar to what you are seeing here.
I did not like this way of working, so I removed this piece of code, and just logged these
messages to a different file, so they were all present, but not clobbering the general logfile.
Is it possible to find memory usage of object in java within application?
I want to have object memory usage to be part of debug output when application runs.
I don't want to connect using external application to VM.
I have a problem that few classes eats up huge amount of memory and causes memory
problems, my app gets crash. I need to find that memory usage (I am working with limited memory resources).
EDIT: I am using java 1.4:/
See my pet project, MemoryMeasurer. A tiny example:
long memory = MemoryMeasurer.measureBytes(new HashMap());
You may also derive more qualitative memory breakdown:
Footprint footprint = ObjectGraphMeasurer.measure(new HashMap());
For example, I used the latter to derive the per entry cost of various data structures, where the overhead is measured in number of objects created, references, and primitives, instead of just bytes (which is also doable). So, next time you use a (default) HashSet, you can be informed that each element in it costs 1 new object (not your element), 5 references, and an int, which is the exact same cost for an entry in HashMap (not unexpectedly, since any HashSet element ends up in a HashMap), and so on.
You can use it on any object graph. If your object graph contains links other structures you do wish to ignore, you should use a predicate to avoid exploring them.
Edit Instrumentation is not available to Java 1.4 (wow, people still use that?!), so the memoryBytes call above wouldn't work for you. But the second would. Then you can write something like this (if you are on a 32bit machine):
long memory = footprint.getObjects() * 8 + footprint.getReferences() * 4 +
footprint.getPrimitives().count(int.class) * 4 +
footprint.getPrimitives().count(long.class) * 8 + ...;
That gives you an approximation. A better answer would be to ceil this to the closest multiple of 16:
long alignedMemory = (x + 15) & (~0xF); //the last part zeros the lowest 4 bits
But the answer might still be off, since if you find, say, 16 booleans, it's one thing if they are found in the same object, and quite another if they are spread in multiple objects (and cause excessive space usage due to aligning). This logic could be implemented as another visitor (similar to how MemoryMeasurer and ObjectGraphMeasurer are implemented - quite simply as you may see), but I didn't bother, since that's what Instrumentation does, so it would only make sense of Java versions below 1.5.
Eclipse MAT is a really good tool to analyze memory.
There are tools that comes with jdk such as jmap and jhat which provides object level details.
The folowing link provides a piece of Java Code computing the size of objects:
http://www.javaworld.com/javaworld/javatips/jw-javatip130.html
I recently started using the findbugs static analysis tool in a java build I was doing. The first report came back with loads of High Priority warnings. Being the obsessive type of person, I was ready to go knock them all out. However, I must be missing something. I get most of the warnings when comparing things. Such as the following code:
public void setSpacesPerLevel(int value)
{
if( value >= 0)
{
spacesPerLevel = value;
}
else
{
spacesPerLevel = 0;
}
}
produces a high priority warning at the if statement that reads.
File: Indenter.java, Line: 60, Type:
BIT_AND_ZZ, Priority: High, Category:
CORRECTNESS Check to see if ((...) &
0) == 0 in
sample.Indenter.setSpacesPerLevel(int)
I am comparing an int to an int, seems like a common thing. I get quite a few of that type of error with similar simple comparisons.
I have alot of other high priority warnings on what appears to be simple code blocks. Am I missing something here? I realize that static analysis can produce false positives, but the errors I am seeing seem too trivial of a case to be a false positive.
This one has me scratching my head as well.
for(int spaces = 0;spaces < spacesPerLevel;spaces++)
{
result = result.concat(" ");
}
Which gives the following findbugs warning:
File: Indenter.java, Line: 160, Type: IL_INFINITE_LOOP, Priority: High, Category: CORRECTNESS
There is an apparent infinite loop in sample.Indenter.indent()
This loop doesn't seem to have a way to terminate (other than by perhaps throwing an exception).
Any ideas?
So basically I have a handful of files and 50-60 high priority warnings similar to the ones above. I am using findbugs 1.3.9 and calling it from the findbugs ant task
UPDATE:
I have this build being executed by a hudson server and had the code being instrumented by Clover for code coverage. When I turned that off, all of my high priority warnings disappeared. That makes sense now. Thanks for the feedback.
UPDATE: I have this build being executed by a hudson server and had the code being instrumented by Clover for code coverage. When I turned that off, all of my high priority warnings disappeared. That makes sense now. Thanks for the feedback.
A side note:
for(int spaces = 0;spaces < spacesPerLevel;spaces++)
{
result = result.concat(" ");
}
If result is a java.lang.String, this may be inefficient, as you do the following steps for each space character:
create a new char[] to hold the result of the concatenation
create a new java.lang.String instance that is wrapped around the character array
If you do this repeatedly, especially when result is already long, this takes a lot of time.
If performance (both time and memory) is important for that method, you should consider using a StringBuilder (not thread-safe) or a StringBuffer (thread-safe).
Are you running Findbugs thru Eclipse plugin, ant or gui? is it possible that the code hasn't recompiled since you ran it (before making changes)?
if setSpacesPerLevel isn't too long, post the output of
javap -v TheClassThatContainssetSpacerPerLevel
As for the second bug, you'd have to show the whole loop before one could say if it was a problem.