mix-object: add function testing

This commit is contained in:
2024-06-19 22:43:22 +08:00
parent 53fb219a05
commit a26c6a8f4f

View File

@@ -12,9 +12,9 @@ import path from "path";
import { FLANG, PREFIX, SW_AUTOVEC, SYSROOT_PREFIX } from "./environment"; import { FLANG, PREFIX, SW_AUTOVEC, SYSROOT_PREFIX } from "./environment";
import { generalCommand, linkerCommand } from "./commands/compiler"; import { generalCommand, linkerCommand } from "./commands/compiler";
import { runcpuOptions } from "./commands/spec"; import { runcpuOptions } from "./commands/spec";
import { renderConfig } from "./spec"; import { checkedSpawnSync, promisifySpawn } from "./cli";
import { checkedSpawnSync } from "./cli";
import { systemdRunOptions } from "./commands/systemd"; import { systemdRunOptions } from "./commands/systemd";
import { spawn } from "child_process";
export interface Linkable { export interface Linkable {
link: (objectPath: (objectNames: string[]) => string[]) => Promise<void>; link: (objectPath: (objectNames: string[]) => string[]) => Promise<void>;
@@ -62,16 +62,9 @@ function mkPop2Bench(spec: SPEC): Bench & Linkable {
} }
async function main() { // Bisect results.
// Just use scalar vanilla version of grid, will it work?
//
// No, does not work.
const useVectorGrid = (object: string) => object !== "grid.fppized.o";
const length = pop2.objectNames.length; const beforeHalfGrid = [
const beforeHalfGrid = [
// 0.336 // 0.336
// Scalar [0, 161): Error, // Scalar [0, 161): Error,
@@ -106,11 +99,9 @@ async function main() {
true, true,
// Vector [241, 246): Error, // Vector [241, 246): Error,
// /home/lyc/workspace/sw-autovec/spec2017/result/CPU2017.677.fpspeed.refspeed.rsf // /home/lyc/workspace/sw-autovec/spec2017/result/CPU2017.677.fpspeed.refspeed.rsf
]; ];
const beforeHalfNoGrid: boolean[] = [
const beforeHalfNoGrid: boolean[] = [
false, false,
// Vector [161, 241): Error // Vector [161, 241): Error
@@ -141,63 +132,48 @@ async function main() {
// Vector [206, 207): ? // Vector [206, 207): ?
// !!! Vector [207, 208): Error // !!! Vector [207, 208): Error
]; ];
const [vBegin, vHalf, vEnd] = binSearch(0, length, beforeHalfNoGrid);
async function bisect(
beforeHalf: boolean[],
/** specify which spec to use */
rangeSPEC: (range: [number, number], index: number) => SPEC,
/** How to get the vector object path */
vector: (name: string) => string,
/** And how to get scalar path. */
scalar: (name: string) => string,
) {
const [vBegin, vHalf, vEnd] = binSearch(0, pop2.objectNames.length, beforeHalf);
// use scalar version if index is in this range. // use scalar version if index is in this range.
const vectorRange: number[][] = [ const vectorRange: [number, number][] = [
[0, length], [vBegin, vHalf],
// [vBegin, vHalf], [vHalf, vEnd],
// [vHalf, vEnd],
]; ];
const specs = [ await Promise.all(vectorRange.map((range, index) => ({
path.join(SW_AUTOVEC, "spec2017"), range,
path.join(SW_AUTOVEC, "spec2017-2") // Assign each range a dedicated SPEC, to avoid race conditions.
].map(mkSPEC); spec: rangeSPEC(range, index),
})).map(async ({ range, spec }) => {
// For each range, linking the objects and test it.
const useVectors = vectorRange.map(([a, b], index) => ({ const [a, b] = range;
useVector: (name: string, index: number) => {
if (name === "grid.fppized.o")
return false;
if (index == 207) {
console.log(`${name} is a bad object!`);
return false;
}
// If index is in range [a, b), use the vector version.
return a <= index && index < b;
},
range: [a, b],
spec: specs[index],
}));
await Promise.all(useVectors.map(async ({ useVector, range, spec }) => {
const buildPathObj = (build: string) => (objname: string) => path.join(spec.buildpath(pop2), build, objname);
const vector = buildPathObj("build_vector");
const scalar = buildPathObj("build_scalar_vanilla");
const pop2Bench = mkPop2Bench(spec); const pop2Bench = mkPop2Bench(spec);
console.log(`Linking objects. Range in [${range[0]}, ${range[1]}) used vector version. others are scalar version.`); console.log(`Linking objects. Range in [${a}, ${b}) used vector version. others are scalar version.`);
await pop2Bench.link(names => await pop2Bench.link(names =>
names.map((obj, index) => names.map((name, index) => {
useVector(obj, index) ? vector(obj) : scalar(obj))); if (name === "grid.fppized.o" || index == 207) {
console.log(`${name} is a bad object!`);
const config = "clang-O2.cfg"; return scalar(name);
const serviceName = `${pop2Bench.benchData().num}-${range[0]}-${range[1]}`;
// Render the config if necessary.
if (false) {
await spec.newConfig(config, renderConfig({
gccdir: PREFIX,
optimize: "-O2",
}));
} }
// If index is in range [a, b), use the vector version.
return a <= index && index < b ? vector(name) : scalar(name);
}));
const serviceName = `${pop2Bench.benchData().num}-${a}-${b}`;
checkedSpawnSync("systemd-run", checkedSpawnSync("systemd-run",
[ [
@@ -209,13 +185,87 @@ async function main() {
"runcpu", "runcpu",
...runcpuOptions({ ...runcpuOptions({
benchmarks: [pop2Bench.benchData().num.toString()], benchmarks: [pop2Bench.benchData().num.toString()],
config, config: "clang-O2.cfg",
workload: "ref", workload: "ref",
buildType: "nobuild", buildType: "nobuild",
outputFormat: ["text", "config"] outputFormat: ["text", "config"]
}), }),
], { stdio: "inherit", env: spec.getEnvironment() }); ], { stdio: "inherit", env: spec.getEnvironment() });
})); }));
} };
main(); (async () => {
const buildPathObj = (buildBase: string) => (build: string) => (objname: string) => path.join(buildBase, build, objname);
const buildDirs = ["build_vector", "build_scalar_vanilla"];
const specs = [
"spec2017",
"spec2017-2",
].map(s => path.resolve(SW_AUTOVEC, s)).map(mkSPEC);
// To test which version works, for grid.
await (async (spec: SPEC) => {
const pop2Bench = mkPop2Bench(spec);
const [vector, scalar] = buildDirs.map(dir => buildPathObj(spec.buildpath(pop2))(dir));
await pop2Bench.link(names => {
return names.flatMap(p => {
if (p == "grid.fppized.o") {
const functionList = [
"grid_.o",
"grid_area_masks_.o",
"grid_calc_tpoints_.o",
"grid_cf_area_avg_.o",
"grid_compute_dz_.o",
"grid_fill_points_.o",
"grid_horiz_grid_internal_.o",
"grid_init_grid1_.o",
"grid_init_grid2_.o",
"grid_landmasks_.o",
"grid_read_bottom_cell_.o",
"grid_read_horiz_grid_.o",
"grid_read_topography_.o",
"grid_read_vert_grid_.o",
"grid_remove_isolated_points_.o",
"grid_remove_points_.o",
"grid_smooth_topography_.o",
"grid_tgrid_to_ugrid_.o",
"grid_topography_bathymetry_.o",
"grid_topography_internal_.o",
"grid_ugrid_to_tgrid_.o",
"grid_vert_grid_internal_.o",
];
return [
...functionList.map(fn => {
const getFunc = (name: string) => path.join(spec.buildpath(pop2), name, fn);
return fn == "grid_landmasks_.o" ? getFunc("function_scalar") : getFunc("function_simd");
}),
path.join(spec.buildpath(pop2), "global-obj.ll.o")
];
}
return vector(p);
});
});
await promisifySpawn(spawn("systemd-run",
[
...systemdRunOptions({
scope: true,
user: true,
unit: "pop2-grid-test",
}),
"runcpu",
...runcpuOptions({
benchmarks: [pop2Bench.benchData().num.toString()],
config: "clang-O2",
workload: "test",
buildType: "nobuild",
outputFormat: ["text", "config"]
}),
], { stdio: "inherit", env: spec.getEnvironment() }));
})(specs[0]);
})();