-
Notifications
You must be signed in to change notification settings - Fork 211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Negative zero causes different results for interpreter mode and compiler mode #2311
Comments
Hi, I find another example that zero not equals to negative zero in both interpreter mode and compiler mode. The datalog file is:
The input of pnlj is: The result of them are both empty. I found this bug in the release version 2.3. Under this version, in compiler mode, if inputs comes from facts file, 0 not equals to -0. but if inputs comes from datalog file. 0 equals to -0. I tested it in the last commit version |
I guess the reason is that if there is |
The problem is that the interpreter uses a bitwise comparison, and the compiler uses a proper floating-point comparison. A fix is possible but requires dealing with corner cases, i.e. weakening/strengthening the bitwise comparison to become functional equivalent with a floating point comparison. The bottom line is that the interpreter must use bit equivalence (no other way due to de-specialization - see PLDI paper). Have a look here: https://codingnest.com/the-little-things-comparing-floating-point-numbers/ Do you have time to fix this issue? I am happy to guide you. The first step is to build a comparison based on bit comparison that deals with the corner cases as an additional constraint. |
I have a question that whether all comparisons under the compiler mode are float-point comparisons? But in compiler mode, in the first example, 0 equals to -0, and in second example, 0 not equals to -0. |
The problem is that Souffle synthesizes relational data structures for the compiler. Hence, the floating-point comparison works for the compiler. However, we cannot do the synthesis perfectly for the interpreter because it would require an exponential number of pre-compiled data structures. To overcome the exponential blowout, we compare floating-point numbers bitwise, which works most of the time. To fix this problem, we would need an extension to bitwise comparison for mimicking floating-point comparison. Something like this: What are the predicates magic1/2 without using fcmp? I am happy to expand more. |
It is interesting! But I'm afraid I don't have time to fix this bug. We are primarily interested in designing and evaluating a new testing approach, I wonder whether it is useful if we report this and other bugs? |
Numerous issues were reported on the same problem, i.e., comparing two floating-point numbers does not work in the interpreter. We need to summarise all previously found issues that relate to this problem. The giveaway is
Would you like to review the issue list and summarise/link the issues? |
Could we have a non-specialized btree for situations like this one? It would probably be a bit slower, but sound. The kind of comparison (signed/unsigned/float-direct/float-margin/float-epsilon/...) of each field would be somehow encoded so that the non-specialized comparator could perform an accurate tuple comparison. This would also allow the interpreter to index inequalities on non-signed values, something that is not allowed yet and has significant impact on the performance: souffle/src/ram/transform/MakeIndex.cpp Lines 100 to 107 in 429676c
And it would also support arbitrary large arities to allow for relations beyond the current limits of the interpreter: souffle/src/interpreter/Util.h Lines 81 to 84 in 4226e49
|
The problem is that we don't know which attributes are floating point numbers ahead of time. Let's assume a relation that has an arity of five. Then, we would require the following specializations for this relation:
where The other option is to provide the comparator as a function pointer with pre-compiled comparators. However, previous experiments showed that this is slow. |
For the sake of soundness, at the cost of the performance, I suggest we add a non-specialized version of the btree where we don't specialize anything:
|
Quentin - I think you are right here. We should switch to slow data structures when we see floating point numbers as attributes and/or the number of arities exceeds. The suggestion would be to have a b-tree data structure with a generic comparator (we provide a relational signature) and arbitrary arity so that the interpreter can fall back to such a data structure if the specialized versions fail to suffice the instance requirements. We had something similar in the past. Either we check out the data structures for the old interpreter or create a new one. |
Hi, I meet another situation that have the same issue as this, but not the same reason. I guess the reason is there is difference in input handler between interpreter. There is an example:
The input of a is:
As in the interpreter, 0.0 not equal to -0.0, so result should be empty. But result is 0.0. So I think this might be a different situation with the one discussed above. |
@ohamel-softwaresecure reported these issues a while ago. Please check old issues. |
Hi, I find another case, I don't know whether they are the same case:
I run with |
I found another case, not sure if they have the same reason, so just report here.
|
Hi,
This problem related to #1378 . But I find that negative zero causes different results for interpreter mode and compiler mode (with
-c
).This is the dl file and input:
orig.zip
In interpreter mode, the result is 0 and -0. In compiler mode, the result is -0. Maybe these shouldn't be different.
Souffle version is 2.3, the newest release version.
The text was updated successfully, but these errors were encountered: