{"id":13640712,"url":"https://github.com/nihui/ruapu","last_synced_at":"2025-04-14T06:06:33.978Z","repository":{"id":223497039,"uuid":"760466190","full_name":"nihui/ruapu","owner":"nihui","description":"Detect CPU features with single-file","archived":false,"fork":false,"pushed_at":"2025-03-25T18:50:27.000Z","size":249,"stargazers_count":388,"open_issues_count":18,"forks_count":43,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-14T06:06:30.355Z","etag":null,"topics":["android","arm","clang","cpu-features","gcc","ios","linux","loongarch","macos","mingw","mips","msvc","powerpc","risc-v","ruapu","s390x","sigill","windows","x86"],"latest_commit_sha":null,"homepage":"https://github.com/nihui/ruapu","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nihui.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-20T13:26:49.000Z","updated_at":"2025-04-12T20:53:37.000Z","dependencies_parsed_at":"2024-04-08T04:29:43.176Z","dependency_job_id":"b9c915ad-9b88-4132-b651-73655ad33494","html_url":"https://github.com/nihui/ruapu","commit_stats":null,"previous_names":["nihui/ruapu"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nihui%2Fruapu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nihui%2Fruapu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nihui%2Fruapu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nihui%2Fruapu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nihui","download_url":"https://codeload.github.com/nihui/ruapu/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248830397,"owners_count":21168272,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","arm","clang","cpu-features","gcc","ios","linux","loongarch","macos","mingw","mips","msvc","powerpc","risc-v","ruapu","s390x","sigill","windows","x86"],"created_at":"2024-08-02T01:01:13.731Z","updated_at":"2025-04-14T06:06:33.950Z","avatar_url":"https://github.com/nihui.png","language":"C","readme":"# ruapu\n\n![GitHub License](https://img.shields.io/github/license/nihui/ruapu?style=for-the-badge)\n![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/nihui/ruapu/ci.yml?style=for-the-badge)\n\nDetect CPU ISA features with single-file\n\n\u003ctable\u003e\n\u003ctr\u003e\u003ctd\u003eCPU\u003c/td\u003e\u003ctd\u003e\u0026#9989; x86, x86-64\u003cbr/\u003e\u0026#9989; arm, aarch64\u003cbr/\u003e\u0026#9989; mips\u003cbr/\u003e\u0026#9989; powerpc\u003cbr/\u003e\u0026#9989; s390x\u003cbr/\u003e\u0026#9989; loongarch\u003cbr/\u003e\u0026#9989; risc-v\u003cbr/\u003e\u0026#9989; openrisc\u003c/td\u003e\u003ctd rowspan=3\u003e\n\n```c\n#define RUAPU_IMPLEMENTATION\n#include \"ruapu.h\"\n\nint main()\n{\n    // initialize ruapu once\n    ruapu_init();\n\n    // now, tell me if this cpu has avx2\n    int has_avx2 = ruapu_supports(\"avx2\");\n\n    // loop all supported features\n    const char* const* supported = ruapu_rua();\n    while (*supported)\n    {\n        fprintf(stderr, \"%s\\n\", *supported);\n        supported++;\n    }\n\n    return 0;\n}\n```\n\n\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eOS\u003c/td\u003e\u003ctd\u003e\u0026#9989; Windows\u003cbr/\u003e\u0026#9989; Linux\u003cbr/\u003e\u0026#9989; macOS\u003cbr/\u003e\u0026#9989; Android\u003cbr/\u003e\u0026#9989; iOS\u003cbr/\u003e\u0026#9989; FreeBSD\u003cbr/\u003e\u0026#9989; NetBSD\u003cbr/\u003e\u0026#9989; OpenBSD\u003cbr/\u003e\u0026#9989; DragonflyBSD\u003cbr/\u003e\u0026#9989; Solaris\u003cbr/\u003e\u0026#9989; SyterKit\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eCompiler\u003c/td\u003e\u003ctd\u003e\u0026#9989; GCC\u003cbr/\u003e\u0026#9989; Clang\u003cbr/\u003e\u0026#9989; MSVC\u003cbr/\u003e\u0026#9989; MinGW\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n#### Best practice for using `ruapu.h` in multiple compilation units\n\n1. Create one `ruapu.c` for your project\n2. `ruapu.c` is **ONLY** `#define RUAPU_IMPLEMENTATION` and `#include \"ruapu.h\"`\n3. Other sources `#include \"ruapu.h\"` but **NO** `#define RUAPU_IMPLEMENTATION`\n\n## Features\n\n* Detect **CPU ISA with single-file**\u0026emsp;\u0026emsp;\u0026emsp;\n  _`sse2`, `avx`, `avx512f`, `neon`, etc._\n* Detect **vendor extended ISA**\u0026emsp;\u0026emsp;\u0026emsp;\u0026emsp;\n  _apple `amx`, risc-v vendor ISA, etc._\n* Detect **richer ISA on Windows ARM**\u0026emsp;\u0026emsp;\n  _`IsProcessorFeaturePresent()` returns little ISA information_\n* Detect **`x86-avx512` on macOS correctly**\u0026emsp;\n  _macOS hides it in `cpuid`_\n* Detect **new CPU's ISA on old systems**\u0026emsp;\n  _they are usually not exposed in `auxv` or `MISA`_\n* Detect **CPU hidden ISA**\u0026emsp;\u0026emsp;\u0026emsp;\u0026emsp;\u0026emsp;\u0026emsp;\u0026emsp;\n  _`fma4` on zen1, ISA in hypervisor, etc._\n\n## Supported ISA _\u0026emsp;(more is comming ... :)_\n\n|CPU|ISA|\n|:---:|---|\n|x86|`mmx` `sse` `sse2` `sse3` `ssse3` `sse41` `sse42` `sse4a` `xop` `avx` `f16c` `fma` `fma4` `avx2` `avx512f` `avx512bw` `avx512cd` `avx512dq` `avx512vl` `avx512vnni` `avx512bf16` `avx512ifma` `avx512vbmi` `avx512vbmi2` `avx512fp16` `avx512er` `avx5124fmaps` `avx5124vnniw` `avxvnni` `avxvnniint8` `avxvnniint16` `avxifma` `avxneconvert` `amxfp16` `amxbf16` `amxint8` `amxtile` `bmi1` `bmi2` `gfni` `aesni` `vaes` `sha1` `sha256` `sha512` `sm3` `sm4` `rdrand` `rdseed` `tsx`|\n|arm|`half` `edsp` `neon` `vfpv4` `idiv`|\n|aarch64|`neon` `vfpv4` `lse` `cpuid` `asimdrdm` `asimdhp` `asimddp` `asimdfhm` `bf16` `i8mm` `frint` `jscvt` `fcma` `mte` `mte2` `sve` `sve2` `svebf16` `svei8mm` `svef32mm` `svef64mm` `sme` `smef16f16` `smef64f64` `smei64i64` `pmull` `crc32` `aes` `sha1` `sha2` `sha3` `sha512` `sm3` `sm4` `svepmull` `svebitperm` `sveaes` `svesha3` `svesm4` `amx`|\n|mips|`msa` `mmi` `sx` `asx` `msa2` `crypto`|\n|powerpc|`vsx`|\n|s390x|`zvector`|\n|loongarch|`lsx` `lasx`|\n|risc-v|`i` `m` `a` `f` `d` `c` `v` `zba` `zbb` `zbc` `zbs` `zbkb` `zbkc` `zbkx` `zcb` `zfa` `zfbfmin` `zfh` `zfhmin` `zicbop` `zicond` `zicsr` `zifencei` `zihintpause` `zmmul` `zvbb` `zvbc` `zvfh` `zvfhmin` `zvfbfmin` `zvfbfwma` `zvkb` `zvl32b` `zvl64b` `zvl128b` `zvl256b` `zvl512b` `zvl1024b` `xtheadba` `xtheadbb` `xtheadbs` `xtheadcondmov` `xtheadfmemidx` `xtheadfmv` `xtheadmac` `xtheadmemidx` `xtheadmempair` `xtheadsync` `xtheadvector` `xtheadvdot` `spacemitvmadot` `spacemitvmadotn` `spacemitvfmadot`|\n|openrisc| `orbis32` `orbis64` `orfpx32` `orfpx64` `orvdx64` |\n\n## Let's ruapu\n\n### ruapu with C\n\n\u003ctable\u003e\n\n\u003ctr\u003e\u003ctd\u003e\n\nCompile ruapu test program\n\n```shell\n# GCC / MinGW\ngcc main.c -o ruapu\n```\n```shell\n# Clang\nclang main.c -o ruapu\n```\n```shell\n# MSVC\ncl.exe /Fe: ruapu.exe main.c\n```\n\u003c/td\u003e\n\u003ctd\u003e\n\nRun ruapu in command line\n\n```shell\n./ruapu\nmmx = 1\nsse = 1\nsse2 = 1\nsse3 = 1\nssse3 = 1\nsse41 = 1\nsse42 = 1\nsse4a = 1\nxop = 0\n... more lines omitted ...\n```\n\n\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n### ruapu with Python\n\n\u003ctable\u003e\n\n\u003ctr\u003e\u003ctd\u003e\n\nCompile and install ruapu library\n\n```shell\n# from pypi\npip3 install ruapu\n```\n\n```shell\n# from source code\npip3 install ./python\n```\n\u003c/td\u003e\n\u003ctd\u003e\n\nUse ruapu in python\n\n```python\nimport ruapu\n\nruapu.supports(\"avx2\")\n# True\n\nruapu.supports(isa=\"avx2\")\n# True\n\nruapu.rua()\n#(mmx', 'sse', 'sse2', 'sse3', 'ssse3', 'sse41', 'sse42', 'avx', 'f16c', 'fma', 'avx2')\n```\n\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n### ruapu with Rust\n\n\u003ctable\u003e\n\n\u003ctr\u003e\u003ctd\u003e\n\nCompile ruapu library\n\n```shell\n# from source code\ncd rust\ncargo build --release\n```\n\u003c/td\u003e\n\u003ctd\u003e\n\nUse ruapu in Rust\n\n```rust\nextern crate ruapu;\n\nfn main() {\n    println!(\"supports neon: {}\", ruapu::supports(\"neon\").unwrap());\n    println!(\"supports avx2: {}\", ruapu::supports(\"avx2\").unwrap());\n    println!(\"rua: {:?}\", ruapu::rua());\n}\n```\n\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n### ruapu with Lua\n\n\u003ctable\u003e\n\n\u003ctr\u003e\u003ctd\u003e\n\nCompile ruapu library\n\n```shell\n# from source code\ncd lua\n# lua binding has been tested on Lua 5.2~5.4\nluarocks make\n```\n\u003c/td\u003e\n\u003ctd\u003e\n\nUse ruapu in Lua\n\n```Lua\nruapu = require \"ruapu\";\nprint(ruapu.supports(\"mmx\"));\nfor _, ext in ipairs(ruapu.rua()) do\n    print(ext);\nend\n```\n\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n### ruapu with Erlang\n\n\u003ctable\u003e\n\n\u003ctr\u003e\u003ctd\u003e\n\nCompile ruapu library\n\n```erlang\n% add this to deps list \n% in your rebar.config\n{ruapu, \"0.1.0\"}\n```\n\u003c/td\u003e\n\u003ctd\u003e\n\nUse ruapu in Erlang `rebar3 shell`\n\n```erlang\nruapu:rua().\n{ok,[\"neon\",\"vfpv4\",\"asimdrdm\",\"asimdhp\",\"asimddp\",\n     \"asimdfhm\",\"bf16\",\"i8mm\",\"pmull\",\"crc32\",\"aes\",\"sha1\",\n     \"sha2\",\"sha3\",\"sha512\",\"amx\"]}\n\u003e ruapu:supports(\"neon\").\ntrue\n\u003e ruapu:supports(neon).\ntrue\n\u003e ruapu:supports(\u003c\u003c\"neon\"\u003e\u003e).\ntrue\n\u003e ruapu:supports(\"avx2\").\nfalse\n\u003e ruapu:supports(avx2).\nfalse\n\u003e ruapu:supports(\u003c\u003c\"avx2\"\u003e\u003e).\nfalse\n```\n\n\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n### ruapu with Fortran\n\n\u003ctable\u003e\n\n\u003ctr\u003e\u003ctd\u003e\n\nCompile ruapu library\n\n```shell\n# from source code\ncd fortran\ncmake -B build\ncmake --build build\n```\n\u003c/td\u003e\n\u003ctd\u003e\n\nUse ruapu in Fortran\n\n```fortran\nprogram main\n    use ruapu, only: ruapu_init, ruapu_supports, ruapu_rua\n    implicit none\n\n    character(len=:), allocatable :: isa_supported(:)\n    integer :: i\n\n    call ruapu_init()\n\n    print *, \"supports sse: \", ruapu_supports(\"sse\")\n    print *, \"supports neon: \", ruapu_supports(\"neon\")\n\n    isa_supported = ruapu_rua()\n    do i = 1, size(isa_supported)\n        print *, trim(isa_supported(i))\n    end do\nend program main\n\n```\n\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n### ruapu with Golang\n\n\u003ctable\u003e\n\n\n\u003ctr\u003e\u003ctd\u003e\n\nCompile ruapu library\n\n```shell\ncd go\ngo build -o ruapu-go\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\nUse ruapu in Golang\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"ruapu-go/ruapu\"\n\t\"strconv\"\n)\n\nfunc main() {\n\truapu.Init()\n\tavx2Status := ruapu.Supports(\"avx2\")\n\tfmt.Println(\"avx2:\" + strconv.Itoa(avx2Status))\n\trua := ruapu.Rua()\n\tfmt.Println(rua)\n}\n```\n\n\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n### ruapu with Haskell\n\n\u003ctable\u003e\n\u003ctr\u003e\u003ctd\u003e\n\nAdd ruapu library to your project\n\n`haskell/Ruapu.hs`, `haskell/ruapu.c` and `ruapu.h` should be copied in your\nproject.\n\n\u003c/td\u003e\n\u003ctd\u003e\n\nUse ruapu in Haskell\n\n```haskell\nimport Ruapu\n-- Ruapu.rua :: IO [String]\n-- Ruapu.supports :: String -\u003e IO Bool\nmain = do\n    Ruapu.init\n    Ruapu.supports \"mmx\" \u003e\u003e= putStrLn . show\n    Ruapu.rua \u003e\u003e= sequence_ . map putStrLn\n```\n\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n### ruapu with Vlang\n\n\u003ctable\u003e\n\n\n\u003ctr\u003e\u003ctd\u003e\n\nCompile ruapu library\n\n```shell\ncd vlang\nv .\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\nUse ruapu in Vlang\n\n```go\nmodule main\n\nimport ruapu\n\nfn main() {\n    ruapu.ruapu_init()\n    mut avx2_status := ruapu.ruapu_supports('avx2')\n    if avx2_status {\n        println('avx2: ' + avx2_status.str())\n    }\n\n    println(ruapu.ruapu_rua())\n}\n```\n\n\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n### ruapu with Pascal\n\n\u003ctable\u003e\n\n\u003ctr\u003e\u003ctd\u003e\n\nCompile ruapu library\n\n```shell\ncd pascal\nsudo apt install fpc\ncmake .\nmake\nfpc ruapu.lpr\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\nUse ruapu in Pascal\n\n```pascal\nprogram ruapu;\n\nuses ruapu_pascal;\n\nvar\n  has_avx2: integer;\n  supported: PPAnsiChar;\nbegin\n  // initialize ruapu once\n  ruapu_init();\n\n  // now, tell me if this cpu has avx2\n  has_avx2 := ruapu_supports('avx2');\n\n  // loop all supported features\n  supported := ruapu_rua();\n  while supported^ \u003c\u003e nil do\n  begin\n      writeln(supported^);\n      inc(supported);\n  end;\n\n  readln();\nend.\n      \n```\n\n\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n### ruapu with Java\n\n\u003ctable\u003e\n\n\u003ctr\u003e\u003ctd\u003e\n\nCompile ruapu library and example\n\n```shell\n./gradlew build\n```\nRun example\n```shell\njava -cp \\\n    ./build/libs/ruapu-1.0-SNAPSHOT.jar \\\n    ./Example.java\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n\nUse ruapu in Java\n\n```java\nimport ruapu.Ruapu;\nimport java.util.*;\n\nclass Example {\n    public static void main(String args[]) {\n        Ruapu ruapu = new Ruapu();\n        \n        System.out.println(\"avx: \" + ruapu.supports(\"avx\")); \n        // avx: 1\n        System.out.println(Arrays.toString(ruapu.rua())); \n        // [mmx, sse, sse2, sse3, ssse3, sse41, sse42, avx, f16c, fma, avx2]\n    }\n}\n      \n```\n\n\n\n\n\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n### ruapu with cangjie\n\n\u003ctable\u003e\n\n\u003ctr\u003e\u003ctd\u003e\n\nCompile ruapu library\n\n```bash\ncd cangjie\ncd c-src\ncmake .\nmake\n```\nrun example\n```bash\ncd cangjie\ncjpm run\n```\nor compile example\n```bash\ncd cangjie\ncjpm build\n./target/release/bin/main\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\nUse ruapu in cangjie\n\n```swift\nimport ruapu.*\nmain(): Int64 {\n    ruapu_init()\n    let neon_supported = ruapu_supports(\"neon\")\n    println(\"supports neon: ${neon_supported}\") \n    let d = ruapu_rua()\n    for (i in d) {\n        println(i)\n    }\n    return 0\n}\n```\n\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n\n### ruapu with Dart\n\n\u003ctable\u003e\n\n\u003ctr\u003e\u003ctd\u003e\n\nCompile ruapu library\n\n```bash\ncd dart\nbash build.sh\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\nUse ruapu in dart\n\n```dart\nvoid main() {\n  var libraryPath =\n  path.join(Directory.current.path, 'build', 'libruapu.so');\n\n  if (Platform.isMacOS) {\n    libraryPath =\n        path.join(Directory.current.path, 'build', 'libruapu.dylib');\n  }\n\n  if (Platform.isWindows) {\n    libraryPath = path.join(\n        Directory.current.path, 'build', 'Debug', 'ruapu.dll');\n  }\n\n  Ruapu ruapu = Ruapu(libraryPath);\n\n  ruapu.init();\n\n  List\u003cString\u003e isas = ruapu.rua();\n  print(\"This CPU Support:\");\n  for (String isa in isas) {\n    print(isa);\n  }\n  print(\"=================\");\n\n  String isaToCheck = 'aes';\n  bool isSupported = ruapu.supports(isaToCheck);\n  print('Does the system support $isaToCheck? $isSupported');\n}\n```\n\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eGithub-hosted runner result (Linux)\u003c/summary\u003e\n\n```\nmmx = 1\nsse = 1\nsse2 = 1\nsse3 = 1\nssse3 = 1\nsse41 = 1\nsse42 = 1\nsse4a = 1\nxop = 0\navx = 1\nf16c = 1\nfma = 1\navx2 = 1\navx512f = 0\navx512bw = 0\navx512cd = 0\navx512dq = 0\navx512vl = 0\navx512vnni = 0\navx512bf16 = 0\navx512ifma = 0\navx512vbmi = 0\navx512vbmi2 = 0\navx512fp16 = 0\navx512er = 0\navx5124fmaps = 0\navx5124vnniw = 0\navxvnni = 0\navxvnniint8 = 0\navxifma = 0\namxfp16 = 0\namxbf16 = 0\namxint8 = 0\namxtile = 0\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eGithub-hosted runner result (macOS)\u003c/summary\u003e\n\n```\nmmx = 1\nsse = 1\nsse2 = 1\nsse3 = 1\nssse3 = 1\nsse41 = 1\nsse42 = 1\nsse4a = 0\nxop = 0\navx = 1\nf16c = 1\nfma = 1\navx2 = 1\navx512f = 0\navx512bw = 0\navx512cd = 0\navx512dq = 0\navx512vl = 0\navx512vnni = 0\navx512bf16 = 0\navx512ifma = 0\navx512vbmi = 0\navx512vbmi2 = 0\navx512fp16 = 0\navx512er = 0\navx5124fmaps = 0\navx5124vnniw = 0\navxvnni = 0\navxvnniint8 = 0\navxifma = 0\namxfp16 = 0\namxbf16 = 0\namxint8 = 0\namxtile = 0\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eGithub-hosted runner result (macOS M1)\u003c/summary\u003e\n\n```\nneon = 1\nvfpv4 = 1\ncpuid = 0\nasimdhp = 1\nasimddp = 1\nasimdfhm = 1\nbf16 = 0\ni8mm = 0\nsve = 0\nsve2 = 0\nsvebf16 = 0\nsvei8mm = 0\nsvef32mm = 0\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eGithub-hosted runner result (Windows)\u003c/summary\u003e\n\n```\nmmx = 1\nsse = 1\nsse2 = 1\nsse3 = 1\nssse3 = 1\nsse41 = 1\nsse42 = 1\nsse4a = 1\nxop = 0\navx = 1\nf16c = 1\nfma = 1\navx2 = 1\navx512f = 0\navx512bw = 0\navx512cd = 0\navx512dq = 0\navx512vl = 0\navx512vnni = 0\navx512bf16 = 0\navx512ifma = 0\navx512vbmi = 0\navx512vbmi2 = 0\navx512fp16 = 0\navx512er = 0\navx5124fmaps = 0\navx5124vnniw = 0\navxvnni = 0\navxvnniint8 = 0\navxifma = 0\namxfp16 = 0\namxbf16 = 0\namxint8 = 0\namxtile = 0\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eFreeBSD/NetBSD/OpenBSD VM result (x86_64)\u003c/summary\u003e\n\n```\nmmx = 1\nsse = 1\nsse2 = 1\nsse3 = 1\nssse3 = 1\nsse41 = 1\nsse42 = 1\nsse4a = 1\nxop = 0\navx = 1\nf16c = 1\nfma = 1\nfma4 = 0\navx2 = 1\navx512f = 0\navx512bw = 0\navx512cd = 0\navx512dq = 0\navx512vl = 0\navx512vnni = 0\navx512bf16 = 0\navx512ifma = 0\navx512vbmi = 0\navx512vbmi2 = 0\navx512fp16 = 0\navx512er = 0\navx5124fmaps = 0\navx5124vnniw = 0\navxvnni = 0\navxvnniint8 = 0\navxifma = 0\namxfp16 = 0\namxbf16 = 0\namxint8 = 0\namxtile = 0\n```\n\n\u003c/details\u003e\n\n## Techniques inside ruapu\nruapu is implemented in C language to ensure the widest possible portability.\n\nruapu determines whether the CPU supports certain instruction sets by trying to execute instructions and detecting whether an `Illegal Instruction` exception occurs. ruapu does not rely on the cpuid instructions and registers related to the CPU architecture, nor does it rely on the `MISA` information and system calls of the operating system. This can help us get more detailed CPU ISA information.\n\n## FAQ\n#### Why is the project named ruapu\n\n\u0026emsp;ruapu is the abbreviation of rua-cpu, which means using various extended instructions to harass and amuse the CPU (rua!). Based on whether the CPU reacts violently (throws an illegal instruction exception), it is inferred whether the CPU supports a certain extended instruction set.\n\n#### Why is ruapu API designed like this\n\n\u0026emsp;We consider gcc builtin functions to be good practice, saying `__builtin_cpu_init()` and `__builtin_cpu_supports()`. ruapu refers to this design, which can be a 1:1 replacement for gcc functions, and supports more operating systems and compilers, giving it better portability.\n\n#### Why does SIGILL occur when executing in debugger or simulator, such as `gdb`, `lldb`, `qemu-user`, `sde` etc.\n\n\u0026emsp;Because debuggers and simulators capture the signal and stop the ruapu signal handler function by default, we can continue execution at this time, or configure it specifically, such as `handle SIGILL nostop` in gdb. ruapu technically cannot prevent programs from stopping in debuggers and emulators\n\n#### How to add detection capabilities for new instructions to ruapu\n\n\u0026emsp;_Assume that the new extended instruction set is named `rua`_\n\n1. Add `RUAPU_INSTCODE(rua, rua-inst-hex) // rua r0,r0` and `RUAPU_ISAENTRY(rua)` in `ruapu.h`\n2. Add `PRINT_ISA_SUPPORT(rua)` in `main.c` to print the detection result\n3. Add entries about `rua` in README.md\n4. Create a pull request!\n\n\u0026emsp;_https://godbolt.org/ is a good helper to view the compiled binary code of instructions._\n\n## Repos that use ruapu\n* [ncnn](https://github.com/Tencent/ncnn) \u0026emsp;_High-performance neural network inference framework_\n* [libllm](https://github.com/ling0322/libllm) \u0026emsp;_Efficient inference of large language models_\n\n## Credits\n\u003ca href=\"https://github.com/nihui/ruapu/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=nihui/ruapu\" /\u003e\n\u003c/a\u003e\n\n### Contribution behavior\n* [@nihui](https://github.com/nihui) \u0026emsp;_Write the initial POC code and ruapu maintainer_\n* [@kernelbin](https://github.com/kernelbin) \u0026emsp;_Implement exception handling for Windows_\n* [@zchrissirhcz](https://github.com/zchrissirhcz) \u0026emsp;_Detect x86 FMA4_\n* [@MollySophia](https://github.com/MollySophia) \u0026emsp;_Fix C++ export symbol_\n* [@strongtz](https://github.com/strongtz) \u0026emsp;_Detect more aarch64 ISA_\n* [@monkeyking](https://github.com/monkeyking) \u0026emsp;_Detect apple arm64 AMX_\n* [@junchao-loongson](https://github.com/junchao-loongson) \u0026emsp;_Add loongarch support_\n* [@ziyao233](https://github.com/ziyao233) \u0026emsp;_Detect more risc-v ISA_\n* [@dreamcmi](https://github.com/dreamcmi) \u0026emsp;_Detect more risc-v ISA_\n* [@cocoa-xu](https://github.com/cocoa-xu) \u0026emsp;_Add FreeBSD support, python support_\n* [@YuzukiTsuru](https://github.com/YuzukiTsuru) \u0026emsp;_Add OpenRISC support_\n* [@whyb](https://github.com/whyb) \u0026emsp;_Detect more x86 AMX*, SHA*, AVX512*, SM*_\n\n## License\nMIT License\n","funding_links":[],"categories":["C"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnihui%2Fruapu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnihui%2Fruapu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnihui%2Fruapu/lists"}