treewide: rename to src/
This commit is contained in:
25
src/algorithm.ts
Normal file
25
src/algorithm.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Performs a binary search within a specified range.
|
||||
* @param begin The starting index of the search range.
|
||||
* @param end The ending index of the search range.
|
||||
* @param beforeHalf A list of predicates indicating conditions before the midpoint.
|
||||
* @returns A tuple containing the indices representing the binary search state: [begin, half, end].
|
||||
*/
|
||||
export function binSearch(begin: number, end: number, beforeHalf: boolean[]): [number, number, number] {
|
||||
const gHalf = () => { return Math.floor((end - begin) / 2) + begin; };
|
||||
|
||||
for (const pred of beforeHalf) {
|
||||
const half = gHalf();
|
||||
if (pred) {
|
||||
// Happens before "half"
|
||||
end = half;
|
||||
} else {
|
||||
begin = half;
|
||||
}
|
||||
}
|
||||
|
||||
const half = gHalf();
|
||||
console.log(`Checking range: [${begin}, ${end}), ${end - begin} objects, mid ${half}`);
|
||||
|
||||
return [begin, half, end];
|
||||
}
|
||||
5
src/build-llvm.ts
Normal file
5
src/build-llvm.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { LLVM_SRC } from "./environment";
|
||||
import { buildLLVMHash } from "./build/llvmPackages";
|
||||
|
||||
|
||||
buildLLVMHash(LLVM_SRC, "e201a0b21b8933b7df79d5cfca2c1e89348aad1f");
|
||||
27
src/build/build.ts
Normal file
27
src/build/build.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
export interface PackageTask {
|
||||
name: string;
|
||||
patchPhase?: (task: PackageTask) => void;
|
||||
configurePhase?: (task: PackageTask) => void;
|
||||
buildPhase?: (task: PackageTask) => void;
|
||||
installPhase?: (task: PackageTask) => void;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export function buildPackage(task: PackageTask) {
|
||||
if (task.patchPhase) {
|
||||
console.log(`${task.name}/patchPhase`);
|
||||
task.patchPhase(task);
|
||||
}
|
||||
if (task.configurePhase) {
|
||||
console.log(`${task.name}/configurePhase`);
|
||||
task.configurePhase(task);
|
||||
}
|
||||
if (task.buildPhase) {
|
||||
console.log(`${task.name}/buildPhase`);
|
||||
task.buildPhase(task);
|
||||
}
|
||||
if (task.installPhase) {
|
||||
console.log(`${task.name}/installPhase`);
|
||||
task.installPhase(task);
|
||||
}
|
||||
}
|
||||
154
src/build/llvmPackages.ts
Normal file
154
src/build/llvmPackages.ts
Normal file
@@ -0,0 +1,154 @@
|
||||
import path from "path";
|
||||
import { GeneralVariable, LLVMVariable, command, variable } from "lyc/commands/cmake";
|
||||
import { SYSROOT_PREFIX } from "lyc/environment";
|
||||
import { PackageTask, buildPackage } from "./build";
|
||||
import { checkedSpawnSync } from "lyc/cli";
|
||||
import os from "os";
|
||||
import { SpawnOptions, spawn } from "child_process";
|
||||
|
||||
export function llvmPackages(src: string, installPrefix: string): PackageTask[] {
|
||||
const LLVM_BUILD = path.join(src, "build-dev");
|
||||
const rm = "rm";
|
||||
const cmake = "cmake";
|
||||
|
||||
const llvmVar: LLVMVariable = {
|
||||
LLVM_ENABLE_PROJECTS: ["clang", "clang-tools-extra", "lld", "openmp"],
|
||||
LLVM_TARGETS_TO_BUILD: ["Sw64"],
|
||||
LIBOMP_ARCH: "Sw64",
|
||||
LIBOMP_USE_ITT_NOTIFY: false,
|
||||
};
|
||||
|
||||
const general: GeneralVariable = {
|
||||
CMAKE_BUILD_TYPE: "Release",
|
||||
CMAKE_INSTALL_PREFIX: installPrefix,
|
||||
CMAKE_SYSROOT: SYSROOT_PREFIX,
|
||||
};
|
||||
|
||||
const env = {
|
||||
...process.env,
|
||||
MAKEFLAGS: ["-j", os.cpus().length].join(" "),
|
||||
LD_LIBRARY_PATH: [
|
||||
path.join(SYSROOT_PREFIX, 'usr', 'lib'),
|
||||
path.join(SYSROOT_PREFIX, 'lib'),
|
||||
].join(':'),
|
||||
};
|
||||
|
||||
const spawnOptions: SpawnOptions = {
|
||||
stdio: "inherit",
|
||||
env,
|
||||
cwd: src,
|
||||
};
|
||||
|
||||
const mkBuildPhase = (build: string) => {
|
||||
checkedSpawnSync(cmake, ["--build", build], spawnOptions);
|
||||
};
|
||||
|
||||
const mkInstallPhase = (build: string) => {
|
||||
checkedSpawnSync(cmake, ["--build", build, "--target", "install"], spawnOptions);
|
||||
};
|
||||
|
||||
function mkLLVMPackage(): PackageTask {
|
||||
const build = path.join(LLVM_BUILD, "llvm");
|
||||
return {
|
||||
name: "llvm",
|
||||
patchPhase: () => {
|
||||
// Apply llvm omp patch
|
||||
checkedSpawnSync("git",
|
||||
[
|
||||
"apply",
|
||||
path.resolve(__dirname, "..", "..", "assets", "omp.diff"),
|
||||
], spawnOptions);
|
||||
},
|
||||
configurePhase: () => {
|
||||
// Configure
|
||||
checkedSpawnSync(cmake, command({
|
||||
definitions: variable({
|
||||
...llvmVar,
|
||||
...general,
|
||||
}),
|
||||
generator: "Ninja",
|
||||
// LLVM cmake root is under /llvm directory
|
||||
pathToSource: path.join(src, "llvm"),
|
||||
pathToBuild: build,
|
||||
}), spawnOptions);
|
||||
},
|
||||
buildPhase: () => mkBuildPhase(build),
|
||||
installPhase: () => mkInstallPhase(build),
|
||||
};
|
||||
}
|
||||
|
||||
function mkLibpgmathPackage(): PackageTask {
|
||||
const build = path.join(LLVM_BUILD, "libpgmath");
|
||||
return {
|
||||
name: "libpgmath",
|
||||
configurePhase: () => {
|
||||
checkedSpawnSync(rm, ["-rf", build], spawnOptions);
|
||||
|
||||
// Configure libpgmath.
|
||||
checkedSpawnSync(cmake, command({
|
||||
definitions: variable({
|
||||
...general,
|
||||
...{
|
||||
CMAKE_C_FLAGS: "-msimd",
|
||||
CMAKE_CXX_FLAGS: "-msimd",
|
||||
CMAKE_C_COMPILER: path.join(installPrefix, "bin", "clang"),
|
||||
CMAKE_CXX_COMPILER: path.join(installPrefix, "bin", "clang++"),
|
||||
} as GeneralVariable,
|
||||
}),
|
||||
generator: "Ninja",
|
||||
pathToSource: path.join(src, "cflang", "runtime", "libpgmath"),
|
||||
pathToBuild: build,
|
||||
}), spawnOptions);
|
||||
},
|
||||
buildPhase: () => mkBuildPhase(build),
|
||||
installPhase: () => mkInstallPhase(build),
|
||||
};
|
||||
}
|
||||
|
||||
function mkCflangPackage(): PackageTask {
|
||||
const build = path.join(LLVM_BUILD, "cflang");
|
||||
return {
|
||||
name: "cflang",
|
||||
configurePhase: () => {
|
||||
checkedSpawnSync(rm, ["-rf", build], spawnOptions);
|
||||
|
||||
// Configure cflang.
|
||||
checkedSpawnSync(cmake, command({
|
||||
definitions: variable({
|
||||
...llvmVar,
|
||||
...general,
|
||||
...{
|
||||
CMAKE_C_COMPILER: path.join(installPrefix, "bin", "clang"),
|
||||
CMAKE_CXX_COMPILER: path.join(installPrefix, "bin", "clang++"),
|
||||
CMAKE_Fortran_COMPILER: path.join(installPrefix, "bin", "flang"),
|
||||
CMAKE_Fortran_COMPILER_ID: "Flang",
|
||||
} as GeneralVariable,
|
||||
// Flang specific variables.
|
||||
FLANG_INCLUDE_DOCS: true,
|
||||
FLANG_LLVM_EXTENSIONS: true,
|
||||
WITH_WERROR: false,
|
||||
LLVM_CONFIG: path.join(installPrefix, "bin", "llvm-config"),
|
||||
}),
|
||||
generator: "Unix Makefiles",
|
||||
pathToSource: path.join(src, "cflang"),
|
||||
pathToBuild: build,
|
||||
}), spawnOptions);
|
||||
},
|
||||
buildPhase: () => mkBuildPhase(build),
|
||||
installPhase: () => mkInstallPhase(build),
|
||||
};
|
||||
}
|
||||
|
||||
return [mkLLVMPackage(), mkLibpgmathPackage(), mkCflangPackage()];
|
||||
|
||||
|
||||
} export function buildLLVMHash(src: string, rev: string) {
|
||||
// Checkout a git rev in some git repo.
|
||||
checkedSpawnSync("git", ["checkout", rev], { stdio: "inherit", cwd: src });
|
||||
checkedSpawnSync("git", ["reset", "--hard", "HEAD"], { stdio: "inherit", cwd: src });
|
||||
|
||||
const llvmInstall = path.join(src, "local", "installed");
|
||||
|
||||
llvmPackages(src, path.join(llvmInstall, rev))
|
||||
.forEach(buildPackage);
|
||||
}
|
||||
28
src/cli.ts
Normal file
28
src/cli.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { ChildProcess, SpawnSyncOptionsWithBufferEncoding, SpawnSyncReturns, spawnSync as rawSpawnSync } from "child_process";
|
||||
|
||||
export function check(result: SpawnSyncReturns<Buffer | string>) {
|
||||
if (result.error)
|
||||
throw result.error;
|
||||
if (result.status !== 0) {
|
||||
throw result.stderr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function checkedSpawnSync(
|
||||
command: string,
|
||||
args: readonly string[],
|
||||
options: SpawnSyncOptionsWithBufferEncoding,
|
||||
): SpawnSyncReturns<Buffer | string> {
|
||||
return check(rawSpawnSync(command, args, options));
|
||||
}
|
||||
|
||||
export function promisifySpawn<T extends ChildProcess>(p: T) {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
p.on("error", err => reject(err));
|
||||
p.on("close", number => {
|
||||
if (number != 0) return reject(number);
|
||||
resolve(p);
|
||||
});
|
||||
});
|
||||
}
|
||||
131
src/commands/cmake.ts
Normal file
131
src/commands/cmake.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
import { optFlag, undefList } from "./common"
|
||||
|
||||
export type CMakeDefinition = {
|
||||
name: string,
|
||||
value: string,
|
||||
type?: CMakeVariableType
|
||||
}
|
||||
|
||||
export type CMakeVariableType = "BOOL" | "FILEPATH" | "PATH" | "STRING" | "INTERNAL"
|
||||
|
||||
/**
|
||||
* General CMake variables.
|
||||
*/
|
||||
export interface GeneralVariable {
|
||||
CMAKE_BUILD_TYPE?: "Debug" | "Release" | "RelWithDebInfo" | "MinSizeRel"
|
||||
BUILD_SHARED_LIBS?: boolean,
|
||||
CMAKE_INSTALL_PREFIX?: string,
|
||||
CMAKE_SYSROOT?: string,
|
||||
CMAKE_C_COMPILER?: string,
|
||||
CMAKE_CXX_COMPILER?: string,
|
||||
CMAKE_Fortran_COMPILER?: string,
|
||||
CMAKE_Fortran_COMPILER_ID?: string,
|
||||
CMAKE_C_FLAGS?: string,
|
||||
CMAKE_CXX_FLAGS?: string,
|
||||
}
|
||||
|
||||
/**
|
||||
* CMake variables suitable for LLVM project.
|
||||
*/
|
||||
export interface LLVMVariable {
|
||||
LLVM_TARGETS_TO_BUILD?: string[]
|
||||
LLVM_ENABLE_CLASSIC_FLANG?: boolean,
|
||||
LLVM_ENABLE_PROJECTS?: ("clang" | "openmp" | "lld" | "clang-tools-extra")[]
|
||||
LIBOMP_ARCH?: "Sw64"
|
||||
LIBOMP_USE_ITT_NOTIFY?: boolean
|
||||
LIBOMP_ENABLE_SHARED?: boolean
|
||||
OPENMP_ENABLE_LIBOMPTARGET?: boolean
|
||||
}
|
||||
|
||||
export interface CFlangCMakeVariable {
|
||||
FLANG_INCLUDE_DIRS?: boolean
|
||||
FLANG_LLVM_EXTENSIONS?: boolean
|
||||
WITH_WERROR?: boolean
|
||||
LLVM_CONFIG?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate cmake definitions, take care of funny cmake string lists.
|
||||
*
|
||||
* @param object A set of cmake variables to generate
|
||||
* @returns A list of cmake definitions, could be passed to CLI
|
||||
*/
|
||||
export function variable(object: Object): CMakeDefinition[] {
|
||||
return Object.entries(object).map(([k, v]) => {
|
||||
if (typeof v === "boolean") {
|
||||
return {
|
||||
name: k,
|
||||
value: v ? "ON" : "OFF",
|
||||
type: "BOOL"
|
||||
}
|
||||
} else if (typeof v === "object" && Array.isArray(v)) {
|
||||
return {
|
||||
name: k,
|
||||
value: v.join(";"),
|
||||
type: "STRING"
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
name: k,
|
||||
value: v,
|
||||
type: "STRING"
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Options for "Generate a Project Buildsystem"
|
||||
* @see https://cmake.org/cmake/help/latest/manual/cmake.1.html#generate-a-project-buildsystem
|
||||
*/
|
||||
export interface CMakeGenerateOptions {
|
||||
pathToBuild?: string
|
||||
pathToSource?: string
|
||||
|
||||
/**
|
||||
* Pre-load a script to populate the cache.
|
||||
* When CMake is first run in an empty build tree, it creates a
|
||||
* CMakeCache.txt file and populates it with customizable settings for the project.
|
||||
* This option may be used to specify a file from which to load cache entries
|
||||
* before the first pass through the project's CMake listfiles.
|
||||
* The loaded entries take priority over the project's default values.
|
||||
* The given file should be a CMake script containing set() commands that use the CACHE option,
|
||||
* not a cache-format file.
|
||||
*/
|
||||
preloadCache?: string
|
||||
|
||||
|
||||
definitions?: CMakeDefinition[]
|
||||
|
||||
/**
|
||||
* Specify a build system generator.
|
||||
*
|
||||
* CMake may support multiple native build systems on certain platforms.
|
||||
* A generator is responsible for generating a particular build system.
|
||||
* Possible generator names are specified in the [cmake-generators(7)](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#manual:cmake-generators(7)) manual.
|
||||
*/
|
||||
generator?: "Unix Makefiles" | "Ninja"
|
||||
|
||||
/**
|
||||
* Specify the cross compiling toolchain file, equivalent to setting CMAKE_TOOLCHAIN_FILE variable.
|
||||
* Relative paths are interpreted as relative to the build directory,
|
||||
* and if not found, relative to the source directory.
|
||||
*
|
||||
* New in version 3.21.
|
||||
*/
|
||||
toolchain?: string
|
||||
}
|
||||
|
||||
export function command(o: CMakeGenerateOptions): string[] {
|
||||
return [
|
||||
...optFlag("-G", o.generator),
|
||||
...undefList(o.definitions, defs => defs.flatMap(def => [
|
||||
"-D",
|
||||
`${def.name}${def.type ? `:${def.type}` : ""}=${def.value}`
|
||||
])),
|
||||
...optFlag("-B", o.pathToBuild),
|
||||
...optFlag("-S", o.pathToSource),
|
||||
]
|
||||
}
|
||||
15
src/commands/common.ts
Normal file
15
src/commands/common.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
export function undefList<T, U>(opt: T | undefined, fn: (opt: T) => U) {
|
||||
return opt === undefined ? [] : fn(opt)
|
||||
}
|
||||
|
||||
export const optFlag = (flag: string, opt: string | undefined) => undefList(opt, opt => [flag, opt])
|
||||
|
||||
/**
|
||||
* Generate a switch flag, like "--rebuild", "--nobuild"
|
||||
*/
|
||||
export const optSwitch = (flag: string, opt: boolean | undefined) => undefList(opt, opt => opt ? [flag] : [])
|
||||
|
||||
export const optMultiFlag = (flag: string, opt: string[] | undefined) =>
|
||||
undefList(
|
||||
opt,
|
||||
opt => opt.flatMap(name => [flag, name]))
|
||||
93
src/commands/compiler.ts
Normal file
93
src/commands/compiler.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { optFlag, optMultiFlag, optSwitch, undefList } from "./common";
|
||||
|
||||
export interface GeneralOptions {
|
||||
output?: string
|
||||
|
||||
sysroot?: string
|
||||
|
||||
outputKind?: "exe" | "object" | "assembly" | "preprocessed"
|
||||
}
|
||||
|
||||
export function generalCommand(options: GeneralOptions) {
|
||||
return [
|
||||
...optFlag("-o", options.output),
|
||||
...undefList(options.outputKind, (opt) => {
|
||||
switch (opt) {
|
||||
case "object":
|
||||
return ["-c"]
|
||||
case "exe":
|
||||
return []
|
||||
case "assembly":
|
||||
return ["-S"]
|
||||
case "preprocessed":
|
||||
return ["-E"]
|
||||
}
|
||||
}),
|
||||
...optFlag("--sysroot", options.sysroot),
|
||||
]
|
||||
}
|
||||
|
||||
interface LinkerOptions {
|
||||
/**
|
||||
* Directory searched for "-l"
|
||||
*/
|
||||
searchDirs?: string[];
|
||||
|
||||
/**
|
||||
* -l libraries.
|
||||
* Static library dependecies must be sorted in topologic order.
|
||||
*/
|
||||
libraries?: string[];
|
||||
}
|
||||
|
||||
export function linkerCommand(options: LinkerOptions) {
|
||||
return [
|
||||
...optMultiFlag("-L", options.searchDirs),
|
||||
...optMultiFlag("-l", options.libraries),
|
||||
]
|
||||
}
|
||||
|
||||
export interface PreprocessorOptions {
|
||||
includeDirs?: string[];
|
||||
}
|
||||
|
||||
export function preprocessorCommand(options: PreprocessorOptions) {
|
||||
return [
|
||||
...optMultiFlag("-I", options.includeDirs),
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* CLI options used for llvm-extract executable.
|
||||
*/
|
||||
export interface ExtractOptions {
|
||||
/**
|
||||
* Functions to extract.
|
||||
*/
|
||||
func?: string[];
|
||||
|
||||
/**
|
||||
* Basic block specifiers.
|
||||
*/
|
||||
bb?: string[];
|
||||
|
||||
output?: string;
|
||||
|
||||
/**
|
||||
* Input file name. If unspecified, llvm-extract reads from stdin
|
||||
*/
|
||||
input?: string;
|
||||
|
||||
asm?: boolean;
|
||||
}
|
||||
|
||||
export function extractCommand(options: ExtractOptions): string[] {
|
||||
return [
|
||||
...optMultiFlag("--func", options.func),
|
||||
...optMultiFlag("--bb", options.bb),
|
||||
...optFlag("-o", options.output),
|
||||
...optSwitch("-S", options.asm),
|
||||
...undefList(options.input, input => [input])
|
||||
];
|
||||
}
|
||||
71
src/commands/spec.ts
Normal file
71
src/commands/spec.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { optFlag, undefList } from "./common"
|
||||
|
||||
export interface RunCPUOptions {
|
||||
/**
|
||||
* Config file, used for compiling flags, compiler versions, etc.
|
||||
*/
|
||||
config?: string
|
||||
|
||||
/**
|
||||
* SPEC workload scale for each benchmark
|
||||
*/
|
||||
workload?: "test" | "train" | "ref"
|
||||
|
||||
/**
|
||||
* Selected benchmarks
|
||||
*/
|
||||
benchmarks?: string[]
|
||||
|
||||
buildType?: "nobuild" | "rebuild" | "plain",
|
||||
|
||||
/**
|
||||
* Default: HTML and text
|
||||
* Meaning: Desired report format.
|
||||
* An output format may be deselected by prepending any of the names with the word "no".
|
||||
* If more than one option is used, separate them by commas or colons.
|
||||
* The values are not case-sensitive.
|
||||
*/
|
||||
outputFormat?: ("all"
|
||||
/** config file used for this run, written as a numbered file in the result directory, for example */
|
||||
| "config"
|
||||
/** Reportable syntax check */
|
||||
| "check"
|
||||
/**
|
||||
* Comma-separated variable.
|
||||
* If you populate spreadsheets from your runs,
|
||||
* you probably should not cut/paste data from text files;
|
||||
* you'll get more accurate data by using --output_format csv.
|
||||
* The csv report includes all runs, more decimal places,
|
||||
* system information, and even the compiler flags.
|
||||
*/
|
||||
| "csv"
|
||||
| "default"
|
||||
| "flags"
|
||||
| "html"
|
||||
| "mail"
|
||||
| "pdf"
|
||||
| "postscript"
|
||||
| "raw"
|
||||
| "screen"
|
||||
/** Plain ASCII text file */
|
||||
| "text")[];
|
||||
}
|
||||
|
||||
export function runcpuOptions(o: RunCPUOptions): string[] {
|
||||
return [
|
||||
...optFlag("-c", o.config),
|
||||
...optFlag("-i", o.workload),
|
||||
...undefList(o.buildType, opt => {
|
||||
switch (opt) {
|
||||
case "nobuild":
|
||||
return ["--nobuild"]
|
||||
case "rebuild":
|
||||
return ["--rebuild"]
|
||||
case "plain":
|
||||
return []
|
||||
}
|
||||
}),
|
||||
...undefList(o.benchmarks, bench => bench),
|
||||
...undefList(o.outputFormat, of => ["--output_format", of.join(",")]),
|
||||
]
|
||||
}
|
||||
31
src/commands/systemd.ts
Normal file
31
src/commands/systemd.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { optFlag, optSwitch } from "./common";
|
||||
|
||||
export interface SystemdRunOptions {
|
||||
/**
|
||||
* Create a transient .scope unit instead of the default transient .service unit (see above).
|
||||
*
|
||||
* @since 206
|
||||
*/
|
||||
scope?: boolean;
|
||||
|
||||
/**
|
||||
* Use this unit name instead of an automatically generated one.
|
||||
*
|
||||
* @since 206
|
||||
*/
|
||||
unit?: string;
|
||||
|
||||
/**
|
||||
* Talk to the service manager of the calling user, rather than the service manager of the system.
|
||||
*/
|
||||
user?: boolean;
|
||||
}
|
||||
|
||||
|
||||
export function systemdRunOptions(o: SystemdRunOptions): string[] {
|
||||
return [
|
||||
...optSwitch("--scope", o.scope),
|
||||
...optFlag("--unit", o.unit),
|
||||
...optSwitch("--user", o.user),
|
||||
];
|
||||
}
|
||||
19
src/environment.ts
Normal file
19
src/environment.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import path from "path"
|
||||
|
||||
export const HOME = path.join("/home", "lyc")
|
||||
|
||||
export const SW_AUTOVEC = path.join(HOME, "workspace", "sw-autovec")
|
||||
|
||||
export const LLVM_SRC = path.join(SW_AUTOVEC, "swllvm-13.0.0-vect0919")
|
||||
export const LLVM_INSTALL = path.join(LLVM_SRC, "local", "installed")
|
||||
|
||||
/// Default toolchain version used in SPEC2017
|
||||
export const PREFIX = path.join(LLVM_INSTALL, "85e4fed0c9e4cd4ab8bce89f307127ccbad31294")
|
||||
export const PREFIXBIN = path.join(PREFIX, "bin")
|
||||
export const LLVM_EXTRACT = path.join(PREFIXBIN, "llvm-extract")
|
||||
|
||||
export const CXX = path.join(PREFIXBIN, "clang++")
|
||||
export const CC = path.join(PREFIXBIN, "clang")
|
||||
export const FLANG = path.join(PREFIXBIN, "flang")
|
||||
|
||||
export const SYSROOT_PREFIX = "/usr/sw/standard-830-6b-test"
|
||||
37
src/gua-spec.ts
Normal file
37
src/gua-spec.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { spawn } from "child_process";
|
||||
import { promisifySpawn } from "lyc/cli";
|
||||
import { runcpuOptions } from "lyc/commands/spec";
|
||||
import { systemdRunOptions } from "lyc/commands/systemd";
|
||||
import { LLVM_INSTALL } from "lyc/environment";
|
||||
import path from "path";
|
||||
import { defaultSPEC, renderConfig } from "lyc/spec";
|
||||
|
||||
|
||||
(async () => {
|
||||
const llvmHash = "31c8e21f40ea654f9d49b3a926acc6ef1f2ca5d5"; // ipa-pure-const.c
|
||||
const llvmPrefix = path.join(LLVM_INSTALL, llvmHash);
|
||||
|
||||
const config = `clang-O2-${llvmHash}.cfg`;
|
||||
|
||||
const spec = defaultSPEC;
|
||||
|
||||
spec.newConfig(config, renderConfig({
|
||||
gccdir: llvmPrefix,
|
||||
optimize: ["-O2", "-msimd"].join(" "),
|
||||
}));
|
||||
|
||||
await promisifySpawn(spawn("systemd-run", [
|
||||
...systemdRunOptions({
|
||||
scope: false,
|
||||
unit: "spec-loadu",
|
||||
user: true,
|
||||
}),
|
||||
"runcpu",
|
||||
...runcpuOptions({
|
||||
benchmarks: ["intspeed"],
|
||||
buildType: "rebuild",
|
||||
config,
|
||||
workload: "ref",
|
||||
})
|
||||
], { env: spec.getEnvironment(), }));
|
||||
})();
|
||||
271
src/mix-object.ts
Normal file
271
src/mix-object.ts
Normal file
@@ -0,0 +1,271 @@
|
||||
/**
|
||||
* Binary search the first bad object in object sets.
|
||||
* Things todo:
|
||||
* 1. Determine the set of vector, or scalar version.
|
||||
* 2. Use the mechanism above, construct such set
|
||||
* 3. Link the set to an executable -> SPEC path, invoke "runcpu"
|
||||
*/
|
||||
|
||||
import { binSearch } from "./algorithm";
|
||||
import { pop2, SPEC, Bench, mkBench, mkSPEC } from "./spec";
|
||||
import path from "path";
|
||||
import { FLANG, PREFIX, SW_AUTOVEC, SYSROOT_PREFIX } from "./environment";
|
||||
import { generalCommand, linkerCommand } from "./commands/compiler";
|
||||
import { runcpuOptions } from "./commands/spec";
|
||||
import { checkedSpawnSync, promisifySpawn } from "./cli";
|
||||
import { systemdRunOptions } from "./commands/systemd";
|
||||
import { spawn } from "child_process";
|
||||
|
||||
export interface Linkable {
|
||||
link: (objectPath: (objectNames: string[]) => string[]) => Promise<void>;
|
||||
}
|
||||
|
||||
function mkPop2Bench(spec: SPEC): Bench & Linkable {
|
||||
const base = mkBench(spec, pop2);
|
||||
return {
|
||||
...base,
|
||||
async link(objectPath) {
|
||||
// Set up environment variables.
|
||||
// FIXME: use -rpath or -rpath-link after I find out why.
|
||||
const objects = objectPath(base.benchData().objectNames);
|
||||
|
||||
const options = [
|
||||
...objects,
|
||||
...linkerCommand({
|
||||
searchDirs: [path.join(PREFIX, "lib"),],
|
||||
}),
|
||||
...generalCommand({
|
||||
output: base.exepath(),
|
||||
outputKind: "exe",
|
||||
sysroot: SYSROOT_PREFIX,
|
||||
}),
|
||||
];
|
||||
|
||||
// Execute the link command
|
||||
const proc = checkedSpawnSync(FLANG, options, {
|
||||
stdio: "inherit",
|
||||
env: {
|
||||
...process.env,
|
||||
LD_LIBRARY_PATH: [
|
||||
path.join(PREFIX, 'lib'),
|
||||
path.join(SYSROOT_PREFIX, 'lib'),
|
||||
path.join(SYSROOT_PREFIX, 'usr', 'lib')
|
||||
].join(':')
|
||||
},
|
||||
});
|
||||
|
||||
if (proc.error) {
|
||||
throw proc.error;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// Bisect results.
|
||||
|
||||
const beforeHalfGrid = [
|
||||
// 0.336
|
||||
|
||||
// Scalar [0, 161): Error,
|
||||
// /home/lyc/workspace/sw-autovec/spec2017/result/CPU2017.671.fpspeed.refspeed.txt
|
||||
// : /home/lyc/workspace/sw-autovec/spec2017/result/CPU2017.664.fpspeed.refspeed.txt
|
||||
// Scalar [161, 322): Correct.
|
||||
|
||||
false,
|
||||
// Scalar [161, 241): Error,
|
||||
// /home/lyc/workspace/sw-autovec/spec2017/result/CPU2017.672.fpspeed.refspeed.txt
|
||||
// Scalar [241, 322): Error,
|
||||
// /home/lyc/workspace/sw-autovec/spec2017-2/result/CPU2017.672.fpspeed.refspeed.rsf
|
||||
// Vector [161, 241): Error,
|
||||
// Vector [241, 322): Error,
|
||||
// /home/lyc/workspace/sw-autovec/spec2017-2/result/CPU2017.673.fpspeed.refspeed.txt
|
||||
|
||||
false,
|
||||
// Vector [241, 281): Error,
|
||||
// /home/lyc/workspace/sw-autovec/spec2017/result/CPU2017.674.fpspeed.refspeed.txt
|
||||
// Vector [281, 322): Correct.
|
||||
|
||||
true,
|
||||
// Vector [241, 261): Error,
|
||||
// /home/lyc/workspace/sw-autovec/spec2017/result/CPU2017.675.fpspeed.refspeed.rsf
|
||||
// Vector [261, 281): Correct.
|
||||
|
||||
true,
|
||||
// Vector [241, 251): Error,
|
||||
// /home/lyc/workspace/sw-autovec/spec2017/result/CPU2017.676.fpspeed.refspeed.txt
|
||||
// Vector [251, 261): Stopped.
|
||||
|
||||
true,
|
||||
// Vector [241, 246): Error,
|
||||
// /home/lyc/workspace/sw-autovec/spec2017/result/CPU2017.677.fpspeed.refspeed.rsf
|
||||
];
|
||||
|
||||
const beforeHalfNoGrid: boolean[] = [
|
||||
false,
|
||||
|
||||
// Vector [161, 241): Error
|
||||
// /home/lyc/workspace/sw-autovec/spec2017/result/CPU2017.679.
|
||||
// Vector [241, 322): Unknown
|
||||
true,
|
||||
|
||||
// Vector [161, 201): Unknown
|
||||
// Vector [201, 241): Error
|
||||
false,
|
||||
|
||||
// Vector [201, 221): Error
|
||||
// /home/lyc/workspace/sw-autovec/spec2017/result/CPU2017.681
|
||||
// Vector [221, 241): Unknown
|
||||
true,
|
||||
|
||||
// Vector [201, 211): Error
|
||||
// Vector [211, 221): Unknown
|
||||
true,
|
||||
|
||||
// Vector [201, 206): Unknown
|
||||
// Vector [206, 211): Error
|
||||
false,
|
||||
|
||||
// Vector [206, 208): Error
|
||||
// Vector [208, 211): ?
|
||||
true,
|
||||
|
||||
// Vector [206, 207): ?
|
||||
// !!! Vector [207, 208): Error
|
||||
];
|
||||
|
||||
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.
|
||||
const vectorRange: [number, number][] = [
|
||||
[vBegin, vHalf],
|
||||
[vHalf, vEnd],
|
||||
];
|
||||
|
||||
await Promise.all(vectorRange.map((range, index) => ({
|
||||
range,
|
||||
// Assign each range a dedicated SPEC, to avoid race conditions.
|
||||
spec: rangeSPEC(range, index),
|
||||
})).map(async ({ range, spec }) => {
|
||||
// For each range, linking the objects and test it.
|
||||
|
||||
const [a, b] = range;
|
||||
|
||||
const pop2Bench = mkPop2Bench(spec);
|
||||
|
||||
console.log(`Linking objects. Range in [${a}, ${b}) used vector version. others are scalar version.`);
|
||||
await pop2Bench.link(names =>
|
||||
names.map((name, index) => {
|
||||
if (name === "grid.fppized.o" || index == 207) {
|
||||
console.log(`${name} is a bad object!`);
|
||||
return scalar(name);
|
||||
}
|
||||
// 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",
|
||||
[
|
||||
...systemdRunOptions({
|
||||
scope: false,
|
||||
unit: `spec-${serviceName}`,
|
||||
user: true,
|
||||
}),
|
||||
"runcpu",
|
||||
...runcpuOptions({
|
||||
benchmarks: [pop2Bench.benchData().num.toString()],
|
||||
config: "clang-O2.cfg",
|
||||
workload: "ref",
|
||||
buildType: "nobuild",
|
||||
outputFormat: ["text", "config"]
|
||||
}),
|
||||
], { stdio: "inherit", env: spec.getEnvironment() });
|
||||
}));
|
||||
};
|
||||
|
||||
(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]);
|
||||
|
||||
})();
|
||||
463
src/spec.ts
Normal file
463
src/spec.ts
Normal file
@@ -0,0 +1,463 @@
|
||||
import * as path from 'path';
|
||||
import * as fs from "fs";
|
||||
import { promisify } from "util";
|
||||
import { SW_AUTOVEC } from "./environment";
|
||||
import { spec } from 'node:test/reporters';
|
||||
import { ChildProcess, ChildProcessByStdio } from 'child_process';
|
||||
import { Readable, Writable } from 'stream';
|
||||
import { Readline } from 'readline/promises';
|
||||
import { createInterface } from 'readline';
|
||||
|
||||
export interface SPECBenchData {
|
||||
objectNames: string[];
|
||||
num: number;
|
||||
name: string;
|
||||
exe: string;
|
||||
}
|
||||
|
||||
export const pop2: SPECBenchData = {
|
||||
objectNames: [
|
||||
"netcdf/attr.o",
|
||||
"netcdf/dim.o",
|
||||
"netcdf/error.o",
|
||||
"netcdf/fort-attio.o",
|
||||
"netcdf/fort-control.o",
|
||||
"netcdf/fort-dim.o",
|
||||
"netcdf/fort-genatt.o",
|
||||
"netcdf/fort-geninq.o",
|
||||
"netcdf/fort-genvar.o",
|
||||
"netcdf/fort-lib.o",
|
||||
"netcdf/fort-misc.o",
|
||||
"netcdf/fort-v2compat.o",
|
||||
"netcdf/fort-var1io.o",
|
||||
"netcdf/fort-varaio.o",
|
||||
"netcdf/fort-vario.o",
|
||||
"netcdf/fort-varmio.o",
|
||||
"netcdf/fort-varsio.o",
|
||||
"netcdf/libvers.o",
|
||||
"netcdf/nc.o",
|
||||
"netcdf/ncx.o",
|
||||
"netcdf/posixio.o",
|
||||
"netcdf/putget.o",
|
||||
"netcdf/string.o",
|
||||
"netcdf/v1hpg.o",
|
||||
"netcdf/v2i.o",
|
||||
"netcdf/var.o",
|
||||
"netcdf/netcdf.o",
|
||||
"netcdf/typeSizes.o",
|
||||
"fort.fppized.o",
|
||||
"mpi.o",
|
||||
"send.o",
|
||||
"recv.o",
|
||||
"collective.o",
|
||||
"req.o",
|
||||
"list.o",
|
||||
"handles.o",
|
||||
"comm.o",
|
||||
"group.o",
|
||||
"time.o",
|
||||
"pack.o",
|
||||
"m_IndexBin_char.fppized.o",
|
||||
"m_IndexBin_integer.fppized.o",
|
||||
"m_IndexBin_logical.fppized.o",
|
||||
"m_List.fppized.o",
|
||||
"m_MergeSorts.fppized.o",
|
||||
"m_Filename.fppized.o",
|
||||
"m_FcComms.fppized.o",
|
||||
"m_Permuter.fppized.o",
|
||||
"m_SortingTools.fppized.o",
|
||||
"m_String.fppized.o",
|
||||
"m_StrTemplate.fppized.o",
|
||||
"m_chars.fppized.o",
|
||||
"m_die.fppized.o",
|
||||
"m_dropdead.fppized.o",
|
||||
"m_FileResolv.fppized.o",
|
||||
"m_flow.fppized.o",
|
||||
"m_inpak90.fppized.o",
|
||||
"m_ioutil.fppized.o",
|
||||
"m_mall.fppized.o",
|
||||
"m_mpif.fppized.o",
|
||||
"m_mpif90.fppized.o",
|
||||
"m_mpout.fppized.o",
|
||||
"m_rankMerge.fppized.o",
|
||||
"m_realkinds.fppized.o",
|
||||
"m_stdio.fppized.o",
|
||||
"m_TraceBack.fppized.o",
|
||||
"m_zeit.fppized.o",
|
||||
"get_zeits.o",
|
||||
"m_MCTWorld.fppized.o",
|
||||
"m_AttrVect.fppized.o",
|
||||
"m_GlobalMap.fppized.o",
|
||||
"m_GlobalSegMap.fppized.o",
|
||||
"m_GlobalSegMapComms.fppized.o",
|
||||
"m_Accumulator.fppized.o",
|
||||
"m_SparseMatrix.fppized.o",
|
||||
"m_Navigator.fppized.o",
|
||||
"m_AttrVectComms.fppized.o",
|
||||
"m_AttrVectReduce.fppized.o",
|
||||
"m_AccumulatorComms.fppized.o",
|
||||
"m_GeneralGrid.fppized.o",
|
||||
"m_GeneralGridComms.fppized.o",
|
||||
"m_SpatialIntegral.fppized.o",
|
||||
"m_SpatialIntegralV.fppized.o",
|
||||
"m_MatAttrVectMul.fppized.o",
|
||||
"m_Merge.fppized.o",
|
||||
"m_GlobalToLocal.fppized.o",
|
||||
"m_ExchangeMaps.fppized.o",
|
||||
"m_ConvertMaps.fppized.o",
|
||||
"m_SparseMatrixDecomp.fppized.o",
|
||||
"m_SparseMatrixToMaps.fppized.o",
|
||||
"m_SparseMatrixComms.fppized.o",
|
||||
"m_SparseMatrixPlus.fppized.o",
|
||||
"m_Router.fppized.o",
|
||||
"m_Rearranger.fppized.o",
|
||||
"m_Transfer.fppized.o",
|
||||
"alloc_mod.fppized.o",
|
||||
"box_rearrange.fppized.o",
|
||||
"iompi_mod.fppized.o",
|
||||
"ionf_mod.fppized.o",
|
||||
"mct_rearrange.fppized.o",
|
||||
"nf_mod.fppized.o",
|
||||
"piodarray.fppized.o",
|
||||
"pio.fppized.o",
|
||||
"pio_kinds.fppized.o",
|
||||
"piolib_mod.fppized.o",
|
||||
"pio_mpi_utils.fppized.o",
|
||||
"pionfatt_mod.fppized.o",
|
||||
"pionfget_mod.fppized.o",
|
||||
"pionfput_mod.fppized.o",
|
||||
"pionfread_mod.fppized.o",
|
||||
"pio_nf_utils.fppized.o",
|
||||
"pionfwrite_mod.fppized.o",
|
||||
"pio_quicksort.fppized.o",
|
||||
"pio_spmd_utils.fppized.o",
|
||||
"pio_support.fppized.o",
|
||||
"pio_types.fppized.o",
|
||||
"pio_utils.fppized.o",
|
||||
"pnetcdfversion.o",
|
||||
"rearrange.fppized.o",
|
||||
"topology.o",
|
||||
"dead_data_mod.fppized.o",
|
||||
"dead_mct_mod.fppized.o",
|
||||
"dead_mod.fppized.o",
|
||||
"ESMF_AlarmClockMod.fppized.o",
|
||||
"ESMF_AlarmMod.fppized.o",
|
||||
"ESMF_BaseMod.fppized.o",
|
||||
"ESMF_BaseTimeMod.fppized.o",
|
||||
"ESMF_CalendarMod.fppized.o",
|
||||
"ESMF_ClockMod.fppized.o",
|
||||
"ESMF_FractionMod.fppized.o",
|
||||
"ESMF_Mod.fppized.o",
|
||||
"ESMF_Stubs.fppized.o",
|
||||
"ESMF_TimeIntervalMod.fppized.o",
|
||||
"ESMF_TimeMod.fppized.o",
|
||||
"f_wrappers.o",
|
||||
"GPTLget_memusage.o",
|
||||
"GPTLprint_memusage.o",
|
||||
"GPTLutil.o",
|
||||
"mct_mod.fppized.o",
|
||||
"Meat.fppized.o",
|
||||
"perf_mod.fppized.o",
|
||||
"perf_utils.fppized.o",
|
||||
"seq_cdata_mod.fppized.o",
|
||||
"seq_comm_mct.fppized.o",
|
||||
"seq_drydep_mod.fppized.o",
|
||||
"seq_flds_indices.fppized.o",
|
||||
"seq_flds_mod.fppized.o",
|
||||
"seq_infodata_mod.fppized.o",
|
||||
"seq_io_mod.fppized.o",
|
||||
"seq_timemgr_mod.fppized.o",
|
||||
"shr_cal_mod.fppized.o",
|
||||
"shr_const_mod.fppized.o",
|
||||
"shr_dmodel_mod.fppized.o",
|
||||
"shr_file_mod.fppized.o",
|
||||
"shr_flux_mod.fppized.o",
|
||||
"shr_jlcp.o",
|
||||
"shr_kind_mod.fppized.o",
|
||||
"shr_log_mod.fppized.o",
|
||||
"shr_map_mod.fppized.o",
|
||||
"shr_mct_mod.fppized.o",
|
||||
"shr_mem_mod.fppized.o",
|
||||
"shr_mpi_mod.fppized.o",
|
||||
"shr_msg_mod.fppized.o",
|
||||
"shr_ncread_mod.fppized.o",
|
||||
"shr_orb_mod.fppized.o",
|
||||
"shr_pcdf_mod.fppized.o",
|
||||
"shr_scam_mod.fppized.o",
|
||||
"shr_strdata_mod.fppized.o",
|
||||
"shr_stream_mod.fppized.o",
|
||||
"shr_string_mod.fppized.o",
|
||||
"shr_sys_mod.fppized.o",
|
||||
"shr_timer_mod.fppized.o",
|
||||
"shr_tInterp_mod.fppized.o",
|
||||
"shr_vmath_fwrap.o",
|
||||
"shr_vmath_mod.fppized.o",
|
||||
"threadutil.o",
|
||||
"wrf_error_fatal.fppized.o",
|
||||
"wrf_message.fppized.o",
|
||||
"atm_comp_mct.fppized.o",
|
||||
"datm_comp_mod.fppized.o",
|
||||
"datm_shr_mod.fppized.o",
|
||||
"dlnd_comp_mod.fppized.o",
|
||||
"lnd_comp_mct.fppized.o",
|
||||
"dice_comp_mod.fppized.o",
|
||||
"ice_comp_mct.fppized.o",
|
||||
"POP_BlocksMod.fppized.o",
|
||||
"POP_BroadcastMod.fppized.o",
|
||||
"POP_CommMod.fppized.o",
|
||||
"POP_ConfigMod.fppized.o",
|
||||
"POP_ConstantsMod.fppized.o",
|
||||
"POP_DistributionMod.fppized.o",
|
||||
"POP_DomainSizeMod.fppized.o",
|
||||
"POP_ErrorMod.fppized.o",
|
||||
"POP_FieldMod.fppized.o",
|
||||
"POP_FinalMod.fppized.o",
|
||||
"POP_GridDimMod.fppized.o",
|
||||
"POP_GridHorzMod.fppized.o",
|
||||
"POP_GridVertMod.fppized.o",
|
||||
"POP_HaloMod.fppized.o",
|
||||
"POP_IOUnitsMod.fppized.o",
|
||||
"POP_InitMod.fppized.o",
|
||||
"POP_KindsMod.fppized.o",
|
||||
"POP_MCT_vars_mod.fppized.o",
|
||||
"POP_RedistributeMod.fppized.o",
|
||||
"POP_ReductionsMod.fppized.o",
|
||||
"POP_SolversMod.fppized.o",
|
||||
"advection.fppized.o",
|
||||
"baroclinic.fppized.o",
|
||||
"barotropic.fppized.o",
|
||||
"blocks.fppized.o",
|
||||
"broadcast.fppized.o",
|
||||
"budget_diagnostics.fppized.o",
|
||||
"cfc11_mod.fppized.o",
|
||||
"cfc_mod.fppized.o",
|
||||
"check_mod.fppized.o",
|
||||
"co2calc.fppized.o",
|
||||
"communicate.fppized.o",
|
||||
"constants.fppized.o",
|
||||
"current_meters.fppized.o",
|
||||
"diag_bsf.fppized.o",
|
||||
"diagnostics.fppized.o",
|
||||
"diags_on_lat_aux_grid.fppized.o",
|
||||
"distribution.fppized.o",
|
||||
"domain.fppized.o",
|
||||
"domain_size.fppized.o",
|
||||
"drifters.fppized.o",
|
||||
"ecosys_mod.fppized.o",
|
||||
"ecosys_parms.fppized.o",
|
||||
"exit_mod.fppized.o",
|
||||
"forcing.fppized.o",
|
||||
"forcing_ap.fppized.o",
|
||||
"forcing_coupled.fppized.o",
|
||||
"forcing_fields.fppized.o",
|
||||
"forcing_pt_interior.fppized.o",
|
||||
"forcing_s_interior.fppized.o",
|
||||
"forcing_sfwf.fppized.o",
|
||||
"forcing_shf.fppized.o",
|
||||
"forcing_tools.fppized.o",
|
||||
"forcing_ws.fppized.o",
|
||||
"gather_scatter.fppized.o",
|
||||
"global_reductions.fppized.o",
|
||||
"grid.fppized.o",
|
||||
"history.fppized.o",
|
||||
"hmix_aniso.fppized.o",
|
||||
"hmix_del2.fppized.o",
|
||||
"hmix_del4.fppized.o",
|
||||
"hmix_gm.fppized.o",
|
||||
"hmix_gm_submeso_share.fppized.o",
|
||||
"horizontal_mix.fppized.o",
|
||||
"hydro_sections.fppized.o",
|
||||
"iage_mod.fppized.o",
|
||||
"ice.fppized.o",
|
||||
"initial.fppized.o",
|
||||
"io.fppized.o",
|
||||
"io_binary.fppized.o",
|
||||
"io_ccsm.fppized.o",
|
||||
"io_netcdf.fppized.o",
|
||||
"io_pio.fppized.o",
|
||||
"io_tools.fppized.o",
|
||||
"io_types.fppized.o",
|
||||
"kinds_mod.fppized.o",
|
||||
"mix_submeso.fppized.o",
|
||||
"movie.fppized.o",
|
||||
"ms_balance.fppized.o",
|
||||
"msg_mod.fppized.o",
|
||||
"named_field_mod.fppized.o",
|
||||
"ocn_communicator.fppized.o",
|
||||
"ocn_comp_mct.fppized.o",
|
||||
"operators.fppized.o",
|
||||
"output.fppized.o",
|
||||
"overflows.fppized.o",
|
||||
"passive_tracer_tools.fppized.o",
|
||||
"passive_tracers.fppized.o",
|
||||
"pressure_grad.fppized.o",
|
||||
"prognostic.fppized.o",
|
||||
"qflux_mod.fppized.o",
|
||||
"registry.fppized.o",
|
||||
"restart.fppized.o",
|
||||
"spacecurve_mod.fppized.o",
|
||||
"state_mod.fppized.o",
|
||||
"step_mod.fppized.o",
|
||||
"surface_hgt.fppized.o",
|
||||
"sw_absorption.fppized.o",
|
||||
"tavg.fppized.o",
|
||||
"tidal_mixing.fppized.o",
|
||||
"time_management.fppized.o",
|
||||
"timers.fppized.o",
|
||||
"topostress.fppized.o",
|
||||
"tracer_types.fppized.o",
|
||||
"vertical_mix.fppized.o",
|
||||
"vmix_const.fppized.o",
|
||||
"vmix_kpp.fppized.o",
|
||||
"vmix_rich.fppized.o",
|
||||
"glc_comp_mct.fppized.o",
|
||||
"ccsm_driver.fppized.o",
|
||||
"map_atmatm_mct.fppized.o",
|
||||
"map_atmice_mct.fppized.o",
|
||||
"map_atmlnd_mct.fppized.o",
|
||||
"map_atmocn_mct.fppized.o",
|
||||
"map_glcglc_mct.fppized.o",
|
||||
"map_iceice_mct.fppized.o",
|
||||
"map_iceocn_mct.fppized.o",
|
||||
"map_lndlnd_mct.fppized.o",
|
||||
"map_ocnocn_mct.fppized.o",
|
||||
"map_rofocn_mct.fppized.o",
|
||||
"map_rofrof_mct.fppized.o",
|
||||
"map_snoglc_mct.fppized.o",
|
||||
"map_snosno_mct.fppized.o",
|
||||
"mrg_x2a_mct.fppized.o",
|
||||
"mrg_x2g_mct.fppized.o",
|
||||
"mrg_x2i_mct.fppized.o",
|
||||
"mrg_x2l_mct.fppized.o",
|
||||
"mrg_x2o_mct.fppized.o",
|
||||
"mrg_x2s_mct.fppized.o",
|
||||
"seq_avdata_mod.fppized.o",
|
||||
"seq_diag_mct.fppized.o",
|
||||
"seq_domain_mct.fppized.o",
|
||||
"seq_flux_mct.fppized.o",
|
||||
"seq_frac_mct.fppized.o",
|
||||
"seq_hist_mod.fppized.o",
|
||||
"seq_rearr_mod.fppized.o",
|
||||
"seq_rest_mod.fppized.o",
|
||||
],
|
||||
exe: "speed_pop2_base.mytest-m64",
|
||||
name: "pop2_s",
|
||||
num: 628,
|
||||
};
|
||||
|
||||
|
||||
export function benchpath(specdir: string, bench: SPECBenchData): string {
|
||||
return path.join(specdir, 'benchspec', 'CPU', `${bench.num}.${bench.name}`);
|
||||
}
|
||||
|
||||
export function exepath(specdir: string, bench: SPECBenchData): string {
|
||||
const benchmarkDir = benchpath(specdir, bench);
|
||||
return path.join(benchmarkDir, 'exe', bench.exe);
|
||||
}
|
||||
|
||||
export function buildpath(specdir: string, bench: SPECBenchData): string {
|
||||
const benchmarkDir = benchpath(specdir, bench);
|
||||
return path.join(benchmarkDir, 'build');
|
||||
}
|
||||
|
||||
export function getEnvironment(specdir: string): NodeJS.ProcessEnv {
|
||||
return {
|
||||
...process.env,
|
||||
SPEC: specdir,
|
||||
PATH: `${path.join(specdir, 'bin')}${path.delimiter}${process.env.PATH}`,
|
||||
};
|
||||
}
|
||||
|
||||
export interface SPEC {
|
||||
newConfig: (name: string, content: string) => Promise<void>;
|
||||
benchpath: (bench: SPECBenchData) => string;
|
||||
exepath: (bench: SPECBenchData) => string;
|
||||
buildpath: (bench: SPECBenchData) => string;
|
||||
getEnvironment: () => NodeJS.ProcessEnv;
|
||||
}
|
||||
|
||||
export function mkSPEC(specRoot: string): SPEC {
|
||||
return {
|
||||
newConfig: async (name: string, content: string) => {
|
||||
await writeFile(path.join(specRoot, "config", name), content);
|
||||
},
|
||||
benchpath: bench => benchpath(specRoot, bench),
|
||||
exepath: bench => exepath(specRoot, bench),
|
||||
buildpath: bench => buildpath(specRoot, bench),
|
||||
getEnvironment: () => getEnvironment(specRoot),
|
||||
};
|
||||
}
|
||||
|
||||
export interface Bench {
|
||||
benchpath: () => string;
|
||||
exepath: () => string;
|
||||
buildpath: () => string;
|
||||
benchData: () => SPECBenchData;
|
||||
spec: () => SPEC;
|
||||
}
|
||||
|
||||
|
||||
export function mkBench(spec: SPEC, bench: SPECBenchData): Bench {
|
||||
return {
|
||||
benchpath: () => spec.benchpath(bench),
|
||||
exepath: () => spec.exepath(bench),
|
||||
buildpath: () => spec.buildpath(bench),
|
||||
benchData: () => bench,
|
||||
spec: () => spec,
|
||||
};
|
||||
}
|
||||
|
||||
export const defaultSPEC = mkSPEC(path.join(SW_AUTOVEC, "spec2017"));
|
||||
|
||||
const specTemplate = fs.readFileSync("assets/specTemplate.cfg").toString("utf-8");
|
||||
|
||||
const writeFile = promisify(fs.writeFile);
|
||||
|
||||
interface ConfigOptions {
|
||||
gccdir: string;
|
||||
optimize: string;
|
||||
}
|
||||
|
||||
export function renderConfig(options: ConfigOptions) {
|
||||
return `# Rendered from TypeScript ${new Date().toLocaleString()}, do not edit!\n\n\n` + specTemplate
|
||||
.replace("@@GCCDIR@@", options.gccdir)
|
||||
.replace("@@OPTIMIZE@@", options.optimize);
|
||||
}
|
||||
|
||||
|
||||
interface SPECResult {
|
||||
format: string;
|
||||
paths: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Monitor SPEC2017 runcpu process in a subprocess.
|
||||
*/
|
||||
export async function watchSPEC<T extends ChildProcessByStdio<null | Writable, Readable, Readable>>(process: T) {
|
||||
const rl = createInterface({
|
||||
input: process.stdout,
|
||||
terminal: false,
|
||||
});
|
||||
|
||||
// Match & extract string like " format CSV -> /path/to/csv"
|
||||
const formatRe = /^\s*format:\s*(\w+)\s*->\s*(.*)$/;
|
||||
|
||||
return await new Promise<SPECResult[]>((resolve, reject) => {
|
||||
let results: SPECResult[] = [];
|
||||
rl.on("line", line => {
|
||||
let match;
|
||||
if ((match = formatRe.exec(line)) != null) {
|
||||
const type = match[1];
|
||||
const paths = match[2].split(',').map(path => path.trim());
|
||||
results.push({
|
||||
format: type,
|
||||
paths: paths,
|
||||
});
|
||||
}
|
||||
// To match if the line contains: "runcpu finished
|
||||
if (line.startsWith("runcpu finished")) {
|
||||
resolve(results);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user