Skip to content

[libc] Add lgamma and lgamma_r stubs for the GPU #102019

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

Merged
merged 1 commit into from
Aug 5, 2024
Merged

Conversation

jhuber6
Copy link
Contributor

@jhuber6 jhuber6 commented Aug 5, 2024

Summary:
These functions are used by the implementation in libc++ and
cause a lot of tests to fail. For now we provide these through the
vendor abstraction until we have a real version. The NVPTX version
doesn't even update the output correctly so these are just temporary.

@llvmbot
Copy link
Member

llvmbot commented Aug 5, 2024

@llvm/pr-subscribers-backend-amdgpu

@llvm/pr-subscribers-libc

Author: Joseph Huber (jhuber6)

Changes

Summary:
These functions are used by the <random> implementation in libc++ and
cause a lot of tests to fail. For now we provide these through the
vendor abstraction until we have a real version. The NVPTX version
doesn't even update the output correctly so these are just temporary.


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

14 Files Affected:

  • (modified) libc/config/gpu/entrypoints.txt (+2)
  • (modified) libc/newhdrgen/yaml/math.yaml (+39)
  • (modified) libc/spec/stdc.td (+8)
  • (modified) libc/src/math/CMakeLists.txt (+2)
  • (modified) libc/src/math/amdgpu/CMakeLists.txt (+24)
  • (modified) libc/src/math/amdgpu/declarations.h (+2)
  • (added) libc/src/math/amdgpu/lgamma.cpp (+19)
  • (added) libc/src/math/amdgpu/lgamma_r.cpp (+24)
  • (added) libc/src/math/lgamma.h (+21)
  • (added) libc/src/math/lgamma_r.h (+20)
  • (modified) libc/src/math/nvptx/CMakeLists.txt (+24)
  • (modified) libc/src/math/nvptx/declarations.h (+1)
  • (added) libc/src/math/nvptx/lgamma.cpp (+20)
  • (added) libc/src/math/nvptx/lgamma_r.cpp (+23)
diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt
index 8d29e7e2e253b..c70dc08490cef 100644
--- a/libc/config/gpu/entrypoints.txt
+++ b/libc/config/gpu/entrypoints.txt
@@ -349,6 +349,8 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.tanhf
     libc.src.math.tgamma
     libc.src.math.tgammaf
+    libc.src.math.lgamma
+    libc.src.math.lgamma_r
     libc.src.math.trunc
     libc.src.math.truncf
 )
diff --git a/libc/newhdrgen/yaml/math.yaml b/libc/newhdrgen/yaml/math.yaml
index ce562c653a6d2..1172184991122 100644
--- a/libc/newhdrgen/yaml/math.yaml
+++ b/libc/newhdrgen/yaml/math.yaml
@@ -2153,3 +2153,42 @@ functions:
       - type: int
       - type: unsigned int
     guard: LIBC_TYPES_HAS_FLOAT128
+  - name: lgamma
+    standards: 
+      - stdc
+    return_type: double
+    arguments:
+      - type: double
+  - name: lgammaf
+    standards: 
+      - stdc
+    return_type: float
+    arguments:
+      - type: float
+  - name: lgammal
+    standards: 
+      - stdc
+    return_type: long double
+    arguments:
+      - type: long double
+  - name: lgamma_r
+    standards: 
+      - stdc
+    return_type: double
+    arguments:
+      - type: double
+      - type: int *
+  - name: lgammaf_r
+    standards: 
+      - stdc
+    return_type: float
+    arguments:
+      - type: float
+      - type: int *
+  - name: lgammal_r
+    standards: 
+      - stdc
+    return_type: long double
+    arguments:
+      - type: long double
+      - type: int *
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 3f68eeb7853ad..623b0449d1e8a 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -767,6 +767,14 @@ def StdC : StandardSpec<"stdc"> {
           GuardedFunctionSpec<"f16divf128", RetValSpec<Float16Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT16_AND_FLOAT128">,
 
           GuardedFunctionSpec<"f16sqrtf128", RetValSpec<Float16Type>, [ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT16_AND_FLOAT128">,
+
+          FunctionSpec<"lgamma", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
+          FunctionSpec<"lgammaf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
+          FunctionSpec<"lgammal", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>]>,
+
+          FunctionSpec<"lgamma_r", RetValSpec<DoubleType>, [ArgSpec<DoubleType, IntPtr>]>,
+          FunctionSpec<"lgammaf_r", RetValSpec<FloatType>, [ArgSpec<FloatType, IntPtr>]>,
+          FunctionSpec<"lgammal_r", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType, IntPtr>]>,
       ]
   >;
 
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index e513d72260fb1..aec94d41ad086 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -448,6 +448,8 @@ add_math_entrypoint_object(tanhf)
 
 add_math_entrypoint_object(tgamma)
 add_math_entrypoint_object(tgammaf)
+add_math_entrypoint_object(lgamma)
+add_math_entrypoint_object(lgamma_r)
 
 add_math_entrypoint_object(totalorder)
 add_math_entrypoint_object(totalorderf)
diff --git a/libc/src/math/amdgpu/CMakeLists.txt b/libc/src/math/amdgpu/CMakeLists.txt
index 7f80f688a2c4b..659acb2868fd7 100644
--- a/libc/src/math/amdgpu/CMakeLists.txt
+++ b/libc/src/math/amdgpu/CMakeLists.txt
@@ -527,3 +527,27 @@ add_entrypoint_object(
     -O2
   VENDOR
 )
+
+add_entrypoint_object(
+  lgamma
+  SRCS
+    lgamma.cpp
+  HDRS
+    ../lgamma.h
+  COMPILE_OPTIONS
+    ${bitcode_link_flags}
+    -O2
+  VENDOR
+)
+
+add_entrypoint_object(
+  lgamma_r
+  SRCS
+    lgamma_r.cpp
+  HDRS
+    ../lgamma_r.h
+  COMPILE_OPTIONS
+    ${bitcode_link_flags}
+    -O2
+  VENDOR
+)
diff --git a/libc/src/math/amdgpu/declarations.h b/libc/src/math/amdgpu/declarations.h
index 98c14ee43cd19..88e2201521b67 100644
--- a/libc/src/math/amdgpu/declarations.h
+++ b/libc/src/math/amdgpu/declarations.h
@@ -82,6 +82,8 @@ float __ocml_remquo_f32(float, float, gpu::Private<int> *);
 double __ocml_remquo_f64(double, double, gpu::Private<int> *);
 double __ocml_tgamma_f64(double);
 float __ocml_tgamma_f32(float);
+double __ocml_lgamma_f64(double);
+double __ocml_lgamma_r_f64(double, gpu::Private<int> *);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/amdgpu/lgamma.cpp b/libc/src/math/amdgpu/lgamma.cpp
new file mode 100644
index 0000000000000..acff4c76734e1
--- /dev/null
+++ b/libc/src/math/amdgpu/lgamma.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of the lgamma function for GPU ---------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/lgamma.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(double, lgamma, (double x)) { return __ocml_lgamma_f64(x); }
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/amdgpu/lgamma_r.cpp b/libc/src/math/amdgpu/lgamma_r.cpp
new file mode 100644
index 0000000000000..0a79988d66e30
--- /dev/null
+++ b/libc/src/math/amdgpu/lgamma_r.cpp
@@ -0,0 +1,24 @@
+//===-- Implementation of the lgamma_r function for GPU -------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/lgamma_r.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(double, lgamma_r, (double x, int *signp)) {
+  int tmp = *signp;
+  double r = __ocml_lgamma_r_f64(x, (gpu::Private<int> *)&tmp);
+  *signp = tmp;
+  return r;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/lgamma.h b/libc/src/math/lgamma.h
new file mode 100644
index 0000000000000..603486765ec39
--- /dev/null
+++ b/libc/src/math/lgamma.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for lgamma ------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_MATH_LGAMMA_H
+#define LLVM_LIBC_SRC_MATH_LGAMMA_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+double lgamma(double x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_LGAMMA_H
+
diff --git a/libc/src/math/lgamma_r.h b/libc/src/math/lgamma_r.h
new file mode 100644
index 0000000000000..1ca6b94c86bb4
--- /dev/null
+++ b/libc/src/math/lgamma_r.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for lgamma_r-----------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_MATH_LGAMMA_R_H
+#define LLVM_LIBC_SRC_MATH_LGAMMA_R_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+double lgamma_r(double x, int *signp);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_LGAMMA_R_H
diff --git a/libc/src/math/nvptx/CMakeLists.txt b/libc/src/math/nvptx/CMakeLists.txt
index 97da80b3dbaa1..a7d546e4f1df1 100644
--- a/libc/src/math/nvptx/CMakeLists.txt
+++ b/libc/src/math/nvptx/CMakeLists.txt
@@ -480,3 +480,27 @@ add_entrypoint_object(
     -O2
   VENDOR
 )
+
+add_entrypoint_object(
+  lgamma
+  SRCS
+    lgamma.cpp
+  HDRS
+    ../lgamma.h
+  COMPILE_OPTIONS
+    ${bitcode_link_flags}
+    -O2
+  VENDOR
+)
+
+add_entrypoint_object(
+  lgamma_r
+  SRCS
+    lgamma_r.cpp
+  HDRS
+    ../lgamma_r.h
+  COMPILE_OPTIONS
+    ${bitcode_link_flags}
+    -O2
+  VENDOR
+)
diff --git a/libc/src/math/nvptx/declarations.h b/libc/src/math/nvptx/declarations.h
index 7bfa934c0142d..6f0bcfe7dce0f 100644
--- a/libc/src/math/nvptx/declarations.h
+++ b/libc/src/math/nvptx/declarations.h
@@ -86,6 +86,7 @@ double __nv_remquo(double, double, int *);
 float __nv_remquof(float, float, int *);
 double __nv_tgamma(double);
 float __nv_tgammaf(float);
+float __nv_lgamma(double);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/nvptx/lgamma.cpp b/libc/src/math/nvptx/lgamma.cpp
new file mode 100644
index 0000000000000..012ccd35bf939
--- /dev/null
+++ b/libc/src/math/nvptx/lgamma.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the lgamma function for GPU ---------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/lgamma.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(double, lgamma, (double x)) { return __nv_lgamma(x); }
+
+} // namespace LIBC_NAMESPACE_DECL
+
diff --git a/libc/src/math/nvptx/lgamma_r.cpp b/libc/src/math/nvptx/lgamma_r.cpp
new file mode 100644
index 0000000000000..aa0a7b9a4b8b9
--- /dev/null
+++ b/libc/src/math/nvptx/lgamma_r.cpp
@@ -0,0 +1,23 @@
+//===-- Implementation of the lgamma_r function for GPU -------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/lgamma_r.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(double, lgamma_r, (double x, int *signp)) {
+  // The NVPTX device library does not export this, just pretend for now.
+  *signp = -1;
+  return __nv_lgamma(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

Copy link

github-actions bot commented Aug 5, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Comment on lines +451 to +452
add_math_entrypoint_object(lgamma)
add_math_entrypoint_object(lgamma_r)
Copy link
Member

Choose a reason for hiding this comment

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

Nit: only type variants of the same function are grouped together (except a few exceptions that should be fixed), so tgamma*, lgamma* and lgamma_r* should be in three separate groups. Definitions are also sorted alphabetically, by function prefix/base name without type suffix.

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(double, lgamma_r, (double x, int *signp)) {
// The NVPTX device library does not export this, just pretend for now.
Copy link
Member

Choose a reason for hiding this comment

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

Nit: maybe prefix this comment with TODO: so that IDEs and other tools can recognize it.


LLVM_LIBC_FUNCTION(double, lgamma_r, (double x, int *signp)) {
// The NVPTX device library does not export this, just pretend for now.
*signp = -1;
Copy link
Contributor

Choose a reason for hiding this comment

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

double result = __nv_lgamma(x);
*signp = (result < 0.0) ? -1 : 1;
return result;

- type: long double
- name: lgamma_r
standards:
- stdc
Copy link
Contributor

Choose a reason for hiding this comment

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

*gamma_r functions are POSIX extensions?

Copy link
Member

Choose a reason for hiding this comment

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

I think it's a glibc extension actually.

FunctionSpec<"lgammaf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
FunctionSpec<"lgammal", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>]>,

FunctionSpec<"lgamma_r", RetValSpec<DoubleType>, [ArgSpec<DoubleType, IntPtr>]>,
Copy link
Contributor

Choose a reason for hiding this comment

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

*gamma_r functions are POSIX extensions?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The lgamma() functions are specified in C99 and POSIX.1-2001. signgam is specified in POSIX.1-2001, but not in C99. The lgamma_r() functions are nonstandard, but present on several other systems.

No standard lol.

Summary:
These functions are used by the <random> implementation in libc++ and
cause a lot of tests to fail. For now we provide these through the
vendor abstraction until we have a real version. The NVPTX version
doesn't even update the output correctly so these are just temporary.
@jhuber6 jhuber6 merged commit 88d2884 into llvm:main Aug 5, 2024
4 of 5 checks passed
@overmighty
Copy link
Member

overmighty commented Aug 6, 2024

This broke the Buildbot builds while the Buildbot master was down. See https://lab.llvm.org/buildbot/#/builders/71/builds/3672 for example.

@overmighty
Copy link
Member

This broke the Buildbot builds while the Buildbot master was down. See https://lab.llvm.org/buildbot/#/builders/71/builds/3672 for example.

Fixed by d798d3b.

@jhuber6 jhuber6 deleted the lgamma branch October 14, 2024 19:20
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.

4 participants