mix-object: add function testing
This commit is contained in:
178
mix-object.ts
178
mix-object.ts
@@ -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]);
|
||||||
|
|
||||||
|
})();
|
||||||
|
|||||||
Reference in New Issue
Block a user