Files
wehub-resource-sync 7254f7b4d1
Build / Build (macos-latest) (push) Waiting to run
Build / Build (ubuntu-latest) (push) Waiting to run
Build / Build (windows-latest) (push) Waiting to run
Build / Analyze (javascript) (push) Waiting to run
Build / Analyze (python) (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 12:37:45 +08:00

188 lines
8.8 KiB
JavaScript

import * as fs from 'fs/promises';
import * as path from 'path';
import * as url from 'url';
import * as xml from '../source/xml.js';
const types = new Map([
['i32_t', 'int32'], ['int32_t', 'int32'], ['i8_t', 'int8'], ['int16_t', 'int16'],
['bool_t', 'boolean'], ['String', 'string'],
['resize_mode_t', 'ResizeMode'], ['nan_propagation_mode_t', 'NanPropagationMode'], ['rounding_mode_t', 'RoundingMode'],
['shape_t', 'shape'], ['tensor_list_t', 'tensor[]'], ['tensor_size_t', 'int32[]'], ['tosa_graph_t', 'graph']
]);
const categories = (name) => {
if (name.includes('CONST')) {
return 'Constant';
}
if (name === 'CUSTOM') {
return 'Custom';
}
if (name.includes('POOL')) {
return 'Pool';
}
if (name === 'RESCALE') {
return 'Quantization';
}
if (name.includes('SHAPE') || name.includes('DIM')) {
return 'Shape';
}
if (name.includes('CONV') || name === 'FULLY_CONNECTED') {
return 'Layer';
}
if (name === 'TRANSPOSE' || name === 'GATHER' || name === 'SCATTER') {
return 'Transform';
}
if (name === 'CLAMP' || name === 'SIGMOID' || name === 'TANH' || name === 'ERF') {
return 'Activation';
}
if (name === 'CONCAT' || name === 'PAD' || name === 'REVERSE' || name === 'SLICE' || name === 'TILE' || name === 'IDENTITY') {
return 'Tensor';
}
return undefined;
};
const main = async () => {
const dirname = path.dirname(url.fileURLToPath(import.meta.url));
const versions = [
{ version: '0.80', dir: 'v0.80' },
{ version: '1.0', dir: 'v1.0' }
];
const files = await Promise.all(versions.map(({ dir }) => {
const xmlPath = path.join(dirname, '..', 'third_party', 'source', 'tosa', dir, 'tosa.xml');
return fs.readFile(xmlPath);
}));
const entries = [];
for (let i = 0; i < versions.length; i++) {
const version = versions[i].version;
const reader = xml.TextReader.open(files[i]);
const document = reader.read();
const root = document.documentElement;
for (const operatorsEl of root.getElementsByTagName('operators')) {
for (const group of operatorsEl.getElementsByTagName('operatorgroup')) {
for (const operator of group.getElementsByTagName('operator')) {
const nameElements = operator.getElementsByTagName('name');
if (nameElements.length === 0) {
continue;
}
const name = nameElements[0].textContent.trim();
if (!name || name === 'RESERVED') {
continue;
}
const entry = { name, version };
const category = categories(name);
if (category) {
entry.category = category;
}
const argumentsElements = operator.getElementsByTagName('arguments');
if (argumentsElements.length > 0) {
const inputs = [];
const outputs = [];
const attributes = [];
for (const arg of argumentsElements[0].getElementsByTagName('argument')) {
const argName = arg.getAttribute('category');
const argLabel = arg.getAttribute('name');
const descElements = arg.getElementsByTagName('description');
const description = descElements.length > 0 ? descElements[0].textContent.trim().replace(/\s+/g, ' ') : '';
const argType = arg.getAttribute('type');
const elementType = arg.getAttribute('tensor-element-type');
const rawType = elementType && elementType !== '-' ? elementType : argType;
const type = types.has(rawType) ? types.get(rawType) : rawType;
const item = { name: argLabel };
if (type) {
item.type = type;
}
if (description) {
item.description = description;
}
if (argName === 'input') {
inputs.push(item);
} else if (argName === 'output') {
outputs.push(item);
} else if (argName === 'attribute') {
attributes.push(item);
}
}
if (inputs.length > 0) {
entry.inputs = inputs;
}
if (outputs.length > 0) {
entry.outputs = outputs;
}
if (attributes.length > 0) {
entry.attributes = attributes;
}
}
const typesupportTypes = [];
const typesElements = operator.getElementsByTagName('types');
if (typesElements.length > 0) {
for (const type of typesElements[0].getElementsByTagName('type')) {
const typeName = type.getAttribute('name');
if (typeName) {
typesupportTypes.push(typeName);
}
}
}
const typesupportElements = operator.getElementsByTagName('typesupport');
if (typesupportTypes.length > 0 && typesupportElements.length > 0) {
const type_constraints = [];
for (const typesupport of typesupportElements) {
const item = { description: "", type_param_str: "", allowed_type_strs: [] };
const profiles = [];
typesupport.getElementsByTagName('profile').forEach((profile) => {
const profileName = profile.getAttribute('name');
if (profileName) {
profiles.push(profileName);
}
});
typesupport.getElementsByTagName('op_profile').forEach((profile) => {
const profileName = profile.getAttribute('name');
if (profileName) {
profiles.push(profileName);
}
});
if (profiles.length === 0) {
profiles.push('BI');
}
profiles.forEach((profile, index) => {
if (!profile.includes('-')) {
profiles[index] = `TOSA-${profile}`;
}
});
item.type_param_str = profiles.join(', ');
const mode = typesupport.getAttribute('mode');
if (mode) {
item.description = mode;
}
const versionAdded = typesupport.getAttribute('version_added');
if (versionAdded) {
item.description = `${item.description ? `${item.description} ` : ''}[v${versionAdded}]`;
}
typesupportTypes.forEach((type) => {
const value = typesupport.getAttribute(type);
if (value) {
item.allowed_type_strs.push(`${type}(${value})`);
}
});
type_constraints.push(item);
}
if (type_constraints.length > 0) {
entry.type_constraints = type_constraints;
}
}
entries.push(entry);
}
}
}
}
entries.sort((a, b) => a.name.localeCompare(b.name) || a.version.localeCompare(b.version));
let output = JSON.stringify(entries, null, 2);
output = output.replace(/\s {8}/g, ' ');
output = output.replace(/,\s {8}/g, ', ');
output = output.replace(/\s {6}}/g, ' }');
const file = path.join(dirname, '..', 'source', 'tosa-metadata.json');
await fs.writeFile(file, output, 'utf-8');
};
await main();