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

Fix for HPCombi #978

Merged
merged 3 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/config-options.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,30 @@ jobs:
- name: "Run Semigroups package's tst/teststandard.g"
uses: gap-actions/run-pkg-tests@v2

enable-hpcombi:
runs-on: "ubuntu-latest"
steps:
- uses: actions/checkout@v3
# Don't use ccache, since sometimes this fails when using -mavx
- name: "Install GAP and clone/compile necessary packages"
uses: gap-actions/setup-gap@v2
with:
GAP_PKGS_TO_BUILD: "digraphs io orb datastructures profiling"
GAPBRANCH: stable-4.12
ABI: 64
- name: "Build Semigroups"
uses: gap-actions/build-pkg@v1
with:
ABI: 64
- name: "Run Semigroups package's tst/teststandard.g"
uses: gap-actions/run-pkg-tests@v2
- uses: gap-actions/process-coverage@v2
- uses: codecov/codecov-action@v2
- name: "Run GAP's tst/testinstall.g"
uses: gap-actions/run-pkg-tests@v2
with:
GAP_TESTFILE: "ci/run-gap-testinstall.g"

with-external-libsemigroups:
runs-on: "ubuntu-latest"
env:
Expand Down
2 changes: 1 addition & 1 deletion GNUmakefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ KEXT_CPPFLAGS += -DHPCOMBI_CONSTEXPR_FUN_ARGS
endif

ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED
KEXT_CXXFLAGS += $(HPCOMBI_CXXFLAGS)
KEXT_CXXFLAGS += @HPCOMBI_CXXFLAGS@
endif

ifdef WITH_INCLUDED_LIBSEMIGROUPS
Expand Down
48 changes: 36 additions & 12 deletions gap/libsemigroups/froidure-pin.gi
Original file line number Diff line number Diff line change
Expand Up @@ -48,29 +48,55 @@ Q -> CanUseLibsemigroupsCongruence(QuotientSemigroupCongruence(Q)));
###########################################################################

DeclareOperation("FroidurePinMemFnRec", [IsSemigroup]);
DeclareOperation("FroidurePinMemFnRec",
[IsSemigroup, IsListOrCollection]);

InstallMethod(FroidurePinMemFnRec, "for a transformation semigroup",
[IsTransformationSemigroup],
function(S)
if DegreeOfTransformationSemigroup(S) <= 16
InstallMethod(FroidurePinMemFnRec, "for a semigroup",
[IsSemigroup], S -> FroidurePinMemFnRec(S, []));

InstallMethod(FroidurePinMemFnRec, "for a semigroup",
[IsSemigroup, IsListOrCollection], {S, coll} -> FroidurePinMemFnRec(S));

InstallMethod(FroidurePinMemFnRec,
"for a transformation semigroup and list or coll.",
[IsTransformationSemigroup, IsListOrCollection],
function(S, coll)
local N;
N := DegreeOfTransformationSemigroup(S);
if IsTransformationCollection(coll) then
N := Maximum(N, DegreeOfTransformationCollection(coll));
elif not IsEmpty(coll) then
Error("Expected a transf. coll. or empty list, found ",
TNAM_OBJ(coll));
fi;
if N <= 16
and IsBound(LIBSEMIGROUPS_HPCOMBI_ENABLED) then
return libsemigroups.FroidurePinTransf16;
elif DegreeOfTransformationSemigroup(S) <= 2 ^ 16 then
elif N <= 2 ^ 16 then
return libsemigroups.FroidurePinTransfUInt2;
elif DegreeOfTransformationSemigroup(S) <= 2 ^ 32 then
elif N <= 2 ^ 32 then
return libsemigroups.FroidurePinTransfUInt4;
else
# Cannot currently test the next line
Error("transformation degree is too high!");
fi;
end);

InstallMethod(FroidurePinMemFnRec, "for a partial perm semigroup",
[IsPartialPermSemigroup],
function(S)
InstallMethod(FroidurePinMemFnRec,
"for a partial perm. semigroup and list or coll.",
[IsPartialPermSemigroup, IsListOrCollection],
function(S, coll)
local N;
N := Maximum(DegreeOfPartialPermSemigroup(S),
CodegreeOfPartialPermSemigroup(S));
if IsPartialPermCollection(coll) then
N := Maximum(N,
DegreeOfPartialPermCollection(coll),
CodegreeOfPartialPermCollection(coll));
elif not IsEmpty(coll) then
Error("Expected a partial perm. coll. or empty list, found ",
TNAM_OBJ(coll));
fi;
if N <= 16 and IsBound(LIBSEMIGROUPS_HPCOMBI_ENABLED) then
return libsemigroups.FroidurePinPPerm16;
elif N <= 2 ^ 16 then
Expand Down Expand Up @@ -860,7 +886,7 @@ function(Constructor, S, coll, opts)
Sort(coll, IsGreensDGreaterThanFunc(Semigroup(coll)));
fi;

R := FroidurePinMemFnRec(S);
R := FroidurePinMemFnRec(S, coll);

# Perform the closure
if IsPartialPermSemigroup(S) or IsTransformationSemigroup(S) then
Expand All @@ -875,8 +901,6 @@ function(Constructor, S, coll, opts)
fi;
if M > N then
# Can't use closure, TODO(later) use copy_closure
# FIXME(later) if M goes larger than the type of R can support this will
# end badly
CppT := R.make();
add_generator := R.add_generator;
for x in GeneratorsOfSemigroup(S) do
Expand Down
2 changes: 1 addition & 1 deletion gapbind14/include/gapbind14/cpp_fn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

namespace gapbind14 {

constexpr size_t MAX_FUNCTIONS = 64;
constexpr size_t MAX_FUNCTIONS = 96;
extern UInt T_GAPBIND14_OBJ;

////////////////////////////////////////////////////////////////////////
Expand Down
36 changes: 18 additions & 18 deletions m4/ax_check_hpcombi.m4
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ AC_DEFUN([AX_CHECK_HPCOMBI], [
AC_MSG_RESULT([$enable_hpcombi])

AS_IF([test "x$enable_hpcombi" = xyes],
[AS_IF([test -f $srcdir/extern/HPCombi/VERSION],
[],
[AS_IF([test -f $srcdir/libsemigroups/extern/HPCombi/VERSION],
[],
[AC_MSG_WARN([HPCombi is not available])
[enable_hpcombi=no]])])

Expand All @@ -40,36 +40,36 @@ AC_DEFUN([AX_CHECK_HPCOMBI], [

AS_IF([test "x$enable_hpcombi" = xyes],
[AC_MSG_CHECKING([the version of HPCombi that's present])
FOUND_HPCOMBI="$(cat $srcdir/extern/HPCombi/VERSION)"
FOUND_HPCOMBI="$(cat $srcdir/libsemigroups/extern/HPCombi/VERSION)"
AC_MSG_RESULT([$FOUND_HPCOMBI])])

AS_IF([test "x$enable_hpcombi" = xyes],
[AX_COMPARE_VERSION($FOUND_HPCOMBI,
[ge],
[AX_COMPARE_VERSION($FOUND_HPCOMBI,
[ge],
$MIN_HPCOMBI_VERSION,
[],
[AC_MSG_WARN([the incorrect version of HPCombi is present, HPCombi is disabled])
[AC_MSG_WARN([the incorrect version of HPCombi is present, HPCombi is disabled])
enable_hpcombi=no])])
dnl # Check if the flags required for HPCombi are supported
AS_IF([test "x$enable_hpcombi" = xyes],
[AX_CHECK_COMPILE_FLAG(-mavx,

dnl # Check if the flags required for HPCombi are supported
AS_IF([test "x$enable_hpcombi" = xyes],
[AX_CHECK_COMPILE_FLAG(-mavx,
AX_APPEND_FLAG(-mavx, [ax_hpcombi_cxxflags_variable]),
[AC_MSG_WARN([flag -mavx not supported, HPCombi is disabled])
enable_hpcombi=no])])

AS_IF([test "x$enable_hpcombi" = xyes],
[AX_CHECK_COMPILE_FLAG(-flax-vector-conversions,
AS_IF([test "x$enable_hpcombi" = xyes],
[AX_CHECK_COMPILE_FLAG(-flax-vector-conversions,
AX_APPEND_FLAG(-flax-vector-conversions, [ax_hpcombi_cxxflags_variable]),
[AC_MSG_WARN([flag -flax-vector-conversions not supported, HPCombi is disabled])
enable_hpcombi=no])])

dnl # Check if the x86intrin.h header is available
AS_IF([test "x$enable_hpcombi" = xyes],
AS_IF([test "x$enable_hpcombi" = xyes],
[AC_CHECK_HEADERS([x86intrin.h], [], [AC_MSG_WARN([header x86intrin.h is required for HPCombi, HPCombi is disabled])
enable_hpcombi=no])])
AS_IF([test "x$enable_hpcombi" = xyes],

AS_IF([test "x$enable_hpcombi" = xyes],
[enable_hpcombi_before_builtin_check=yes])

AS_IF([test "x$enable_hpcombi" = xyes], [CHECK_INTRINSIC([_mm_blendv_epi8],[__m128i{},__m128i{},__m128i{}])])
Expand Down Expand Up @@ -100,10 +100,10 @@ AC_DEFUN([AX_CHECK_HPCOMBI], [
AC_SUBST(LIBSEMIGROUPS_HPCOMBI_ENABLED, yes))

dnl # check for HPCombi's preprocessor macro
AS_IF([test "x$enable_hpcombi" = xyes],
AS_IF([test "x$enable_hpcombi" = xyes],
[AC_MSG_CHECKING([for HPCOMBI_CONSTEXPR_FUN_ARGS])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[using T = int; constexpr int exec(T f()) { return f(); }
constexpr int foo() { return 1; }
static_assert(exec(foo) == 1, "Failed exec");]]
Expand Down
81 changes: 71 additions & 10 deletions src/to_cpp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
#include <algorithm> // for max, min, sort
#include <cstddef> // for size_t
#include <cstdint> // for uint32_t
#include <exception> // for exception
#include <functional> // for __unwrap_reference<>::type
#include <memory> // for make_unique, unique_ptr
#include <string> // for string
#include <type_traits> // for decay_t, is_same, conditional_t
Expand Down Expand Up @@ -444,12 +442,28 @@ namespace gapbind14 {
x[i] = i;
}
}
template <typename TransfType>
TransfType new_transf(size_t N) {
return TransfType(N);
}

#ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED
template <>
inline HPCombi::Transf16 new_transf(size_t N) {
if (N > 16) {
ErrorQuit("expected transformation of degree at most 16, found %d",
(Int) N,
0L);
}
return HPCombi::Transf16();
}
#endif

} // namespace detail

template <typename Scalar>
struct to_cpp<Transf<0, Scalar>> {
using cpp_type = Transf<0, Scalar>;
template <typename TransfType>
struct ToTransf {
using cpp_type = TransfType;

cpp_type operator()(Obj t) const {
if (!IS_PLIST(t)) {
Expand Down Expand Up @@ -477,7 +491,7 @@ namespace gapbind14 {
(Int) DEG_TRANS(x));
}

cpp_type result(N);
cpp_type result = detail::new_transf<cpp_type>(N);
if (TNUM_OBJ(x) == T_TRANS2) {
detail::to_cpp_transf(
result, ADDR_TRANS2(x), std::min(DEG_TRANS(x), N));
Expand All @@ -492,6 +506,20 @@ namespace gapbind14 {
}
};

template <typename Scalar>
struct to_cpp<Transf<0, Scalar>> : ToTransf<Transf<0, Scalar>> {};

#ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED
template <>
struct to_cpp<HPCombi::Transf16> : public ToTransf<HPCombi::Transf16> {};

template <>
struct to_cpp<HPCombi::Transf16&> : ToTransf<HPCombi::Transf16> {};

template <>
struct to_cpp<HPCombi::Transf16 const&> : ToTransf<HPCombi::Transf16> {};
#endif

////////////////////////////////////////////////////////////////////////
// Partial perms
////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -532,11 +560,29 @@ namespace gapbind14 {
x[i] = undef;
}
}

template <typename PPermType>
PPermType new_pperm(size_t N) {
return PPermType(N);
}

#ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED
template <>
inline HPCombi::PPerm16 new_pperm(size_t N) {
if (N > 16) {
ErrorQuit("expected partial perm of degree at most 16, found %d",
(Int) N,
0L);
}
return HPCombi::PPerm16();
}
#endif

} // namespace detail

template <typename Scalar>
struct to_cpp<PPerm<0, Scalar>> {
using cpp_type = PPerm<0, Scalar>;
template <typename PPermType>
struct ToPPerm {
using cpp_type = PPermType;

cpp_type operator()(Obj t) const {
if (!IS_PLIST(t)) {
Expand Down Expand Up @@ -573,7 +619,8 @@ namespace gapbind14 {
(Int) M);
}

cpp_type result(N);
cpp_type result = detail::new_pperm<cpp_type>(N);

if (TNUM_OBJ(x) == T_PPERM2) {
detail::to_cpp_pperm(result, ADDR_PPERM2(x), DEG_PPERM2(x));
} else if (TNUM_OBJ(x) == T_PPERM4) {
Expand All @@ -598,6 +645,20 @@ namespace gapbind14 {
}
};

template <typename Scalar>
struct to_cpp<PPerm<0, Scalar>> : ToPPerm<PPerm<0, Scalar>> {};

#ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED
template <>
struct to_cpp<HPCombi::PPerm16> : ToPPerm<HPCombi::PPerm16> {};

template <>
struct to_cpp<HPCombi::PPerm16&> : ToPPerm<HPCombi::PPerm16> {};

template <>
struct to_cpp<HPCombi::PPerm16 const&> : ToPPerm<HPCombi::PPerm16> {};
#endif

////////////////////////////////////////////////////////////////////////
// Bipartition
////////////////////////////////////////////////////////////////////////
Expand Down
Loading