Skip to content
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

[MLIR][Presburger] Fix reduce bug in Fraction class and add tests #68298

Merged
merged 6 commits into from
Oct 6, 2023

Conversation

Abhinav271828
Copy link
Contributor

@Abhinav271828 Abhinav271828 commented Oct 5, 2023

Modified Fraction.reduce() to work with negative fractions as well.
Added tests to verify the implementation of arithmetic and relational operators on Fractions.

@Abhinav271828 Abhinav271828 requested a review from a team as a code owner October 5, 2023 10:20
@llvmbot llvmbot added libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. mlir mlir:presburger labels Oct 5, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Oct 5, 2023

@llvm/pr-subscribers-mlir
@llvm/pr-subscribers-libcxx

@llvm/pr-subscribers-mlir-presburger

Changes

We modify Fraction.reduce() to work with negative fractions as well.
We add tests to verify the implementation of arithmetic and relational operators on Fractions.


Full diff: https://github.com/llvm/llvm-project/pull/68298.diff

5 Files Affected:

  • (added) libcxx/modules/std/mdspan.cppm (+33)
  • (added) libcxx/modules/std/print.cppm (+25)
  • (modified) mlir/include/mlir/Analysis/Presburger/Fraction.h (+9-7)
  • (modified) mlir/unittests/Analysis/Presburger/CMakeLists.txt (+1)
  • (added) mlir/unittests/Analysis/Presburger/FractionTest.cpp (+51)
diff --git a/libcxx/modules/std/mdspan.cppm b/libcxx/modules/std/mdspan.cppm
new file mode 100644
index 000000000000000..40426cce3fce8c2
--- /dev/null
+++ b/libcxx/modules/std/mdspan.cppm
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+module;
+#include <mdspan>
+
+export module std:mdspan;
+export namespace std {
+#if _LIBCPP_STD_VER >= 23
+  // [mdspan.extents], class template extents
+  using std::extents;
+
+  // [mdspan.extents.dextents], alias template dextents
+  using std::dextents;
+
+  // [mdspan.layout], layout mapping
+  using std::layout_left;
+  using std::layout_right;
+  // using std::layout_stride;
+
+  // [mdspan.accessor.default], class template default_accessor
+  using std::default_accessor;
+
+  // [mdspan.mdspan], class template mdspan
+  using std::mdspan;
+#endif // _LIBCPP_STD_VER >= 23
+} // namespace std
diff --git a/libcxx/modules/std/print.cppm b/libcxx/modules/std/print.cppm
new file mode 100644
index 000000000000000..02362633c6d9fbb
--- /dev/null
+++ b/libcxx/modules/std/print.cppm
@@ -0,0 +1,25 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+module;
+#include <print>
+
+export module std:print;
+export namespace std {
+#if _LIBCPP_STD_VER >= 23
+  // [print.fun], print functions
+  using std::print;
+  using std::println;
+
+  using std::vprint_nonunicode;
+#  ifndef _LIBCPP_HAS_NO_UNICODE
+  using std::vprint_unicode;
+#  endif // _LIBCPP_HAS_NO_UNICODE
+#endif   // _LIBCPP_STD_VER >= 23
+} // namespace std
diff --git a/mlir/include/mlir/Analysis/Presburger/Fraction.h b/mlir/include/mlir/Analysis/Presburger/Fraction.h
index 74127a900d53ed2..a410f528e1f8001 100644
--- a/mlir/include/mlir/Analysis/Presburger/Fraction.h
+++ b/mlir/include/mlir/Analysis/Presburger/Fraction.h
@@ -30,7 +30,8 @@ struct Fraction {
   Fraction() = default;
 
   /// Construct a Fraction from a numerator and denominator.
-  Fraction(const MPInt &oNum, const MPInt &oDen = MPInt(1)) : num(oNum), den(oDen) {
+  Fraction(const MPInt &oNum, const MPInt &oDen = MPInt(1))
+      : num(oNum), den(oDen) {
     if (den < 0) {
       num = -num;
       den = -den;
@@ -38,7 +39,8 @@ struct Fraction {
   }
   /// Overloads for passing literals.
   Fraction(const MPInt &num, int64_t den = 1) : Fraction(num, MPInt(den)) {}
-  Fraction(int64_t num, const MPInt &den = MPInt(1)) : Fraction(MPInt(num), den) {}
+  Fraction(int64_t num, const MPInt &den = MPInt(1))
+      : Fraction(MPInt(num), den) {}
   Fraction(int64_t num, int64_t den) : Fraction(MPInt(num), MPInt(den)) {}
 
   // Return the value of the fraction as an integer. This should only be called
@@ -102,7 +104,7 @@ inline bool operator>=(const Fraction &x, const Fraction &y) {
 inline Fraction reduce(const Fraction &f) {
   if (f == Fraction(0))
     return Fraction(0, 1);
-  MPInt g = gcd(f.num, f.den);
+  MPInt g = gcd(abs(f.num), abs(f.den));
   return Fraction(f.num / g, f.den / g);
 }
 
@@ -122,22 +124,22 @@ inline Fraction operator-(const Fraction &x, const Fraction &y) {
   return reduce(Fraction(x.num * y.den - x.den * y.num, x.den * y.den));
 }
 
-inline Fraction& operator+=(Fraction &x, const Fraction &y) {
+inline Fraction &operator+=(Fraction &x, const Fraction &y) {
   x = x + y;
   return x;
 }
 
-inline Fraction& operator-=(Fraction &x, const Fraction &y) {
+inline Fraction &operator-=(Fraction &x, const Fraction &y) {
   x = x - y;
   return x;
 }
 
-inline Fraction& operator/=(Fraction &x, const Fraction &y) {
+inline Fraction &operator/=(Fraction &x, const Fraction &y) {
   x = x / y;
   return x;
 }
 
-inline Fraction& operator*=(Fraction &x, const Fraction &y) {
+inline Fraction &operator*=(Fraction &x, const Fraction &y) {
   x = x * y;
   return x;
 }
diff --git a/mlir/unittests/Analysis/Presburger/CMakeLists.txt b/mlir/unittests/Analysis/Presburger/CMakeLists.txt
index 7b0124ee24c352e..b6ce273e35a0ee7 100644
--- a/mlir/unittests/Analysis/Presburger/CMakeLists.txt
+++ b/mlir/unittests/Analysis/Presburger/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_mlir_unittest(MLIRPresburgerTests
+  FractionTest.cpp
   IntegerPolyhedronTest.cpp
   IntegerRelationTest.cpp
   LinearTransformTest.cpp
diff --git a/mlir/unittests/Analysis/Presburger/FractionTest.cpp b/mlir/unittests/Analysis/Presburger/FractionTest.cpp
new file mode 100644
index 000000000000000..aafa689588c921b
--- /dev/null
+++ b/mlir/unittests/Analysis/Presburger/FractionTest.cpp
@@ -0,0 +1,51 @@
+#include "mlir/Analysis/Presburger/Fraction.h"
+#include "./Utils.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using namespace mlir;
+using namespace presburger;
+
+TEST(FractionTest, getAsInteger) {
+  Fraction f(3, 1);
+  EXPECT_EQ(f.getAsInteger(), MPInt(3));
+}
+
+TEST(FractionTest, nearIntegers) {
+  Fraction f(52, 14);
+
+  EXPECT_EQ(floor(f), 3);
+  EXPECT_EQ(ceil(f), 4);
+}
+
+TEST(FractionTest, reduce) {
+  Fraction f(20, 35), g(-56, 63);
+  EXPECT_EQ(f, Fraction(4, 7));
+  EXPECT_EQ(g, Fraction(-8, 9));
+}
+
+TEST(FractionTest, arithmetic) {
+  Fraction f(3, 4), g(-2, 3);
+
+  EXPECT_EQ(f / g, Fraction(-9, 8));
+  EXPECT_EQ(f * g, Fraction(-1, 2));
+  EXPECT_EQ(f + g, Fraction(1, 12));
+  EXPECT_EQ(f - g, Fraction(17, 12));
+
+  f /= g;
+  EXPECT_EQ(f, Fraction(-9, 8));
+  f *= g;
+  EXPECT_EQ(f, Fraction(3, 4));
+  f += g;
+  EXPECT_EQ(f, Fraction(Fraction(1, 12)));
+  f -= g;
+  EXPECT_EQ(f, Fraction(3, 4));
+}
+
+TEST(FractionTest, relational) {
+  Fraction f(2, 5), g(3, 7);
+  ASSERT_TRUE(f < g);
+  ASSERT_FALSE(g < f);
+
+  EXPECT_EQ(f, Fraction(4, 10));
+}
\ No newline at end of file

@Groverkss Groverkss self-requested a review October 5, 2023 10:26
Copy link
Member

@Groverkss Groverkss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the libcxx changes

@phyBrackets phyBrackets removed the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Oct 5, 2023
@ldionne ldionne removed the request for review from a team October 5, 2023 19:15
@Superty Superty merged commit 014912a into llvm:main Oct 6, 2023
3 checks passed
@Superty
Copy link
Member

Superty commented Oct 6, 2023

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants