188 lines
8.8 KiB
JavaScript
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();
|