Thank you very much, that looks promising. Though if I look at your congigure.ac script, also extremely daunting and far above my current level of understanding. I guess I'll start with the autoconf manual then.
Op di 26 mrt 2024 om 16:04 schreef Vincent Dorie <vdo...@gmail.com>: > > Hi Jesse, > > What I've done is to use a mix of compile-time detection of compiler SIMD > support and run-time detection of SIMD hardware support. At package load, > SIMD-specific versions of functions are installed in a symbol table. It's not > perfect and it can be hard to support evolving platforms, especially now that > ARM is more prevalent. However, it does allow for distribution on CRAN as it > uses only autoconf, POSIX make, and no specific compiler. > > At compile time: > 1. Use a configure script to detect the platform and any SIMD instructions > supported by the compiler. This is also the time to identify the compiler > flags necessary to enable instruction sets. Unlike what the existing autoconf > macros do, you can ignore whether or not the host system supports the > instruction sets (with the exception when compiling with Solaris Studio - it > won't let you load a binary with instructions not supported by the host, even > if they cannot be executed). > 2. Use makefiles to conditionally compile different versions of the functions > you want, one for each level of instruction set supported by the compiler, > using the flags detected above. They all should be in different files with > different symbols. For example: partition_sse2.c defines partition_sse2(), > partition_avx.c defines partition_avx(), etc., while partition.c defines > partition_c() - a fall-back compiled without any SIMD instructions. Note that > echoing compilations with SIMD flags will trigger a check warning, as those > units are not inherently portable. That is addressed below. > > At run time: > 1. On package load, detect what instruction sets are supported by the host. > On x86 machines, this usually involves a call to cpuid. > 2. For the maximum level of instruction set supported by the host, install > the relevant symbol for each function into a symbol table. Using the example > above, a header defines an external function pointer partition(), which gets > set to one of the SIMD-specific implementations. > > In setting that up, I found Agner Fog's notes on CPU dispatching to be > extremely helpful. They can be found here: https://www.agner.org/optimize. I > use this strategy in the dbarts package, the code for which is here: > https://github.com/vdorie/dbarts. > > Best, > Vince > > On Tue, Mar 26, 2024 at 10:45 AM Dirk Eddelbuettel <e...@debian.org> wrote: >> >> >> On 26 March 2024 at 10:53, jesse koops wrote: >> | How can I make this portable and CRAN-acceptable? >> >> But writing (or borrowing ?) some hardware detection via either configure / >> autoconf or cmake. This is no different than other tasks decided at >> install-time. >> >> Start with 'Writing R Extensions', as always, and work your way up from >> there. And if memory serves there are already a few other packages with SIMD >> at CRAN so you can also try to take advantage of the search for a 'token' >> (here: 'SIMD') at the (unofficial) CRAN mirror at GitHub: >> >> https://github.com/search?q=org%3Acran%20SIMD&type=code >> >> Hth, Dirk >> >> -- >> dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org >> >> ______________________________________________ >> R-package-devel@r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-package-devel ______________________________________________ R-package-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel