Intrinsics API
The backend API powering https://simd.jaytux.com
Preparation
- Set up the project's sources (recommended to just use Intellij IDEA, and have it figure out everything for you, which should work out of the box). Alternatively, the
./gradlewwrapper can be used to build the project. - Create an environment file (
.env) in the root directory of the project, with the following variables:DATABASE_URL: The JDBC URL to the database; for example:jdbc:sqlite:./intrinsics.sqlitefor a local SQLite databasejdbc:mariadb://localhost:3306/intrinsicsfor a MariaDB database (served on the local machine at port 3306), which should already be running
DATABASE_DRIVER: The JDBC driver class name; for example:org.sqlite.JDBCfor SQLiteorg.mariadb.jdbc.Driverfor MariaDB
DATABASE_USER: the username to connect to the database; not required for SQLiteDATABASE_PASSWORD: the password to connect to the database; not required for SQLite
- (Optional) change the default port in the
src/main/resources/application.yamlconfiguration file. - Get the intrinsics data from the Intel Intrinsics Guide and post-process the data (I am planning to automate this in the future, stand by).
- The downloaded data is a ZIP-file, with the relevant data files being
files/data.jsandfiles/perf2.js. - Post-process
files/data.jsto be a valid XML file (when downloaded, it's an XML string in a JS variable):- Remove the
var data = "prefix at the beginning of the file - Remove the
";suffix at the end of the file - Replace all
\nwith actual newlines, and all\"with", and then remove all trailing\
- Remove the
- Post-process
files/perf2.jsto be a valid JSON file (when downloaded, it's a JSON string in a JS variable):- Remove the
perf2_js =prefix at the beginning of the file - Replace all
{l:by{"l":, and all,t:by,"t":
- Remove the
- The downloaded data is a ZIP-file, with the relevant data files being
- At this point, you are ready to load the data into the database using the application. Run
./gradlew run -reload /path/to/post-processed/data.js /path/to/post-processed/perf2.js - Finally, you can start the application using
./gradlew run
You can also use the ./package.sh script to build a standalone executable (with bundled JVM).You can also use the ./package.sh script to build a standalone executable (with bundled JVM). It uses the Gradle shadowJar target together with jpackage.
Running
By default, the application runs on port 42024. You can start it using ./gradlew run.
To reload the database (it drops all data, then re-parses everything), use ./gradlew run -reload /path/to/xml /path/to/json.
API
Most of the API is paginated. The default page size is 100, and the default page number is 0. Each paginated response has the following format:
{
"page": <page number>,
"totalPages": <total number of pages>,
"items": []
}
Typically, you can use the "root" API endpoint (e.g. /all) to get the first page of results, and get any page by using the /{page} query parameter (e.g. /all/3). There is one notable exception (/search), where the page number is specified as a query parameter (/search?page=3). Finally, the details endpoint (/details/{id}) is not paginated, and returns a single object.
GET /all
Gets a (paginated) list of all intrinsics. For each intrinsic, the following fields are returned:
{
"id": "<UUID string>",
"name": "<function name of the intrinsic>"
}
Other pages can be requested using the GET /all/{page} endpoint (GET /all is equivalent to GET /all/0).
GET /cpuid
Gets a (paginated) list of all CPUIDs in the database. Each CPUID can be used as a filter for the /search endpoint. The data is a simple list of strings. Examples include PREFETCHI, SSE2, AVX, etc.
GET /tech
Gets a (paginated) list of all technologies in the database. Each technology can be used as a filter for the /search endpoint. The data is a simple list of strings. The full list (at the moment of writing) is:
AMXAVX-512AVX_ALLMMXOtherSSE_ALLSVML
GET /category
Gets a (paginated) list of all categories in the database. Each category can be used as a filter for the /search endpoint. The data is a simple list of strings. Examples include Logical, OS-Targeted, Swizzle, etc.
GET /types
Gets a (paginated) list of all C/C++(-like) types used by the intrinsics. The types can be used as filter for the /search endpoint (but currently only based on return type). The data is a simple list of strings. Examples include __int16, __m128 const *, string literal, etc.
GET /search
Searches the database using the given filters. The filters are passed as query parameters, and can be combined. All filters are optional. The following filters are available:
name=[string]: searches based on the name of the intrinsic; employs fuzzy-search (usingLIKE %it%)return=[string]: searches based on the return type of the intrinsic; exact search onlycpuid=[*]: searches based on the CPUID of the intrinsic; exact search onlytech=[*]: searches based on the technology of the intrinsic; exact search onlycategory=[*]: searches based on the category of the intrinsic; exact search onlydesc=[string]: searches based on the description of the intrinsic; employs fuzzy-search (usingLIKE %it%)page=[int]: specifies the page number to return (default is 0)
Parameters marked by [*] are JSON-lists (so you should pass them as cpuid=["PREFETCHI", "SSE2"]). They are considered to be OR-ed together (i.e. the results will contain a mix of all intrinsics matching either of the CPUIDs (from the example)).
Passing no filters is equivalent to using GET /all, and data is returned in the same format:
{
"page": <page number>,
"totalPages": <total number of pages>,
"items": [
{
"id": "<UUID string>",
"name": "<function name of the intrinsic>"
}
]
}
GET /details/{id}
Gets the details for a single, specific intrinsic. The following data is returned:
{
"id": "<UUID string>",
"name": "<function name of the intrinsic>",
"returnType": "<return type of the intrinsic>",
"returnVar": "<variable name for the return value, as used in the description; can be null>",
"description": "<description of the intrinsic>",
"operations": "<operation of the intrinsic in pseudocode>",
"category": "<category>",
"cpuid": "<CPUID>",
"tech": "<technology>",
"params": [
{
"name": "<parameter name>",
"type": "<parameter type>"
}
],
"instructions": [
{
"mnemonic": "<instruction mnemonic>",
"xed": "<Intel XED code>",
"form": "<instruction argument form>"
}
],
"performance": [
{
"platform": "<platform name>",
"latency": <latency in cycles; can be null>,
"throughput": <throughput in CPI; can be null>
}
]
}
GET /version
Gets version information for the data. The following data is returned:
{
"intelVersion": "M.m.p (Major.minor.patch version as reported by Intel)",
"intelUpdate": "yyyy-MM-dd (date of Intel's last update prior to scraping)",
"scrapeDate": "yyyy-MM-dd (date of last update)"
}