@@ -192,7 +192,13 @@ template <typename HostFuncType, HostFuncType func> class FolderFactory {
192
192
193
193
// Define host runtime libraries that can be used for folding and
194
194
// fill their description if they are available.
195
- enum class LibraryVersion { Libm, PgmathFast, PgmathRelaxed, PgmathPrecise };
195
+ enum class LibraryVersion {
196
+ Libm,
197
+ LibmExtensions,
198
+ PgmathFast,
199
+ PgmathRelaxed,
200
+ PgmathPrecise
201
+ };
196
202
template <typename HostT, LibraryVersion> struct HostRuntimeLibrary {
197
203
// When specialized, this class holds a static constexpr table containing
198
204
// all the HostRuntimeLibrary for functions of library LibraryVersion
@@ -277,6 +283,64 @@ struct HostRuntimeLibrary<std::complex<HostT>, LibraryVersion::Libm> {
277
283
static constexpr HostRuntimeMap map{table};
278
284
static_assert (map.Verify(), " map must be sorted" );
279
285
};
286
+ // Note regarding cmath:
287
+ // - cmath does not have modulo and erfc_scaled equivalent
288
+ // - C++17 defined standard Bessel math functions std::cyl_bessel_j
289
+ // and std::cyl_neumann that can be used for Fortran j and y
290
+ // bessel functions. However, they are not yet implemented in
291
+ // clang libc++ (ok in GNU libstdc++). Instead, the Posix libm
292
+ // extensions are used when available below.
293
+
294
+ #if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
295
+ // / Define libm extensions
296
+ // / Bessel functions are defined in POSIX.1-2001.
297
+
298
+ template <> struct HostRuntimeLibrary <float , LibraryVersion::LibmExtensions> {
299
+ using F = FuncPointer<float , float >;
300
+ using FN = FuncPointer<float , int , float >;
301
+ static constexpr HostRuntimeFunction table[]{
302
+ FolderFactory<F, F{::j0f}>::Create (" bessel_j0" ),
303
+ FolderFactory<F, F{::j1f}>::Create (" bessel_j1" ),
304
+ FolderFactory<FN, FN{::jnf}>::Create (" bessel_jn" ),
305
+ FolderFactory<F, F{::y0f}>::Create (" bessel_y0" ),
306
+ FolderFactory<F, F{::y1f}>::Create (" bessel_y1" ),
307
+ FolderFactory<FN, FN{::ynf}>::Create (" bessel_yn" ),
308
+ };
309
+ static constexpr HostRuntimeMap map{table};
310
+ static_assert (map.Verify(), " map must be sorted" );
311
+ };
312
+
313
+ template <> struct HostRuntimeLibrary <double , LibraryVersion::LibmExtensions> {
314
+ using F = FuncPointer<double , double >;
315
+ using FN = FuncPointer<double , int , double >;
316
+ static constexpr HostRuntimeFunction table[]{
317
+ FolderFactory<F, F{::j0}>::Create (" bessel_j0" ),
318
+ FolderFactory<F, F{::j1}>::Create (" bessel_j1" ),
319
+ FolderFactory<FN, FN{::jn}>::Create (" bessel_jn" ),
320
+ FolderFactory<F, F{::y0}>::Create (" bessel_y0" ),
321
+ FolderFactory<F, F{::y1}>::Create (" bessel_y1" ),
322
+ FolderFactory<FN, FN{::yn}>::Create (" bessel_yn" ),
323
+ };
324
+ static constexpr HostRuntimeMap map{table};
325
+ static_assert (map.Verify(), " map must be sorted" );
326
+ };
327
+
328
+ template <>
329
+ struct HostRuntimeLibrary <long double , LibraryVersion::LibmExtensions> {
330
+ using F = FuncPointer<long double , long double >;
331
+ using FN = FuncPointer<long double , int , long double >;
332
+ static constexpr HostRuntimeFunction table[]{
333
+ FolderFactory<F, F{::j0l}>::Create (" bessel_j0" ),
334
+ FolderFactory<F, F{::j1l}>::Create (" bessel_j1" ),
335
+ FolderFactory<FN, FN{::jnl}>::Create (" bessel_jn" ),
336
+ FolderFactory<F, F{::y0l}>::Create (" bessel_y0" ),
337
+ FolderFactory<F, F{::y1l}>::Create (" bessel_y1" ),
338
+ FolderFactory<FN, FN{::ynl}>::Create (" bessel_yn" ),
339
+ };
340
+ static constexpr HostRuntimeMap map{table};
341
+ static_assert (map.Verify(), " map must be sorted" );
342
+ };
343
+ #endif
280
344
281
345
// / Define pgmath description
282
346
#if LINK_WITH_LIBPGMATH
@@ -409,6 +473,8 @@ static const HostRuntimeMap *GetHostRuntimeMap(
409
473
switch (version) {
410
474
case LibraryVersion::Libm:
411
475
return GetHostRuntimeMapVersion<LibraryVersion::Libm>(resultType);
476
+ case LibraryVersion::LibmExtensions:
477
+ return GetHostRuntimeMapVersion<LibraryVersion::LibmExtensions>(resultType);
412
478
case LibraryVersion::PgmathPrecise:
413
479
return GetHostRuntimeMapVersion<LibraryVersion::PgmathPrecise>(resultType);
414
480
case LibraryVersion::PgmathRelaxed:
@@ -454,6 +520,13 @@ static const HostRuntimeFunction *SearchHostRuntime(const std::string &name,
454
520
return hostFunction;
455
521
}
456
522
}
523
+ if (const auto *map{
524
+ GetHostRuntimeMap (LibraryVersion::LibmExtensions, resultType)}) {
525
+ if (const auto *hostFunction{
526
+ SearchInHostRuntimeMap (*map, name, resultType, argTypes)}) {
527
+ return hostFunction;
528
+ }
529
+ }
457
530
return nullptr ;
458
531
}
459
532
0 commit comments