[R-pkg-devel] using portable simd instructions

jesse koops je@@e@koop@ @end|ng |rom gm@||@com
Wed Mar 27 08:35:17 CET 2024


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 <vdorie using 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 <edd using 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 | edd using debian.org
>>
>> ______________________________________________
>> R-package-devel using r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-package-devel



More information about the R-package-devel mailing list