Unverified Commit e2c67397 authored by SparkSnail's avatar SparkSnail Committed by GitHub
Browse files

support local windows in hybrid mode (#3353)

parent b6988062
...@@ -12,8 +12,8 @@ import { getLogger, Logger } from '../../../common/log'; ...@@ -12,8 +12,8 @@ import { getLogger, Logger } from '../../../common/log';
import { TrialConfigMetadataKey } from '../../common/trialConfigMetadataKey'; import { TrialConfigMetadataKey } from '../../common/trialConfigMetadataKey';
import { EnvironmentInformation, EnvironmentService } from '../environment'; import { EnvironmentInformation, EnvironmentService } from '../environment';
import { TrialConfig } from '../../common/trialConfig'; import { TrialConfig } from '../../common/trialConfig';
import { getExperimentRootDir, isAlive } from '../../../common/utils'; import { getExperimentRootDir, isAlive, getNewLine } from '../../../common/utils';
import { execMkdir, runScript, execCopydir } from '../../common/util'; import { execMkdir, runScript, getScriptName, execCopydir } from '../../common/util';
@component.Singleton @component.Singleton
export class LocalEnvironmentService extends EnvironmentService { export class LocalEnvironmentService extends EnvironmentService {
...@@ -53,8 +53,8 @@ export class LocalEnvironmentService extends EnvironmentService { ...@@ -53,8 +53,8 @@ export class LocalEnvironmentService extends EnvironmentService {
public async refreshEnvironmentsStatus(environments: EnvironmentInformation[]): Promise<void> { public async refreshEnvironmentsStatus(environments: EnvironmentInformation[]): Promise<void> {
environments.forEach(async (environment) => { environments.forEach(async (environment) => {
const jobpidPath: string = `${environment.runnerWorkingFolder}/pid`; const jobpidPath: string = `${path.join(environment.runnerWorkingFolder, 'pid')}`;
const runnerReturnCodeFilePath: string = `${environment.runnerWorkingFolder}/code`; const runnerReturnCodeFilePath: string = `${path.join(environment.runnerWorkingFolder, 'code')}`;
/* eslint-disable require-atomic-updates */ /* eslint-disable require-atomic-updates */
try { try {
// check if pid file exist // check if pid file exist
...@@ -88,6 +88,32 @@ export class LocalEnvironmentService extends EnvironmentService { ...@@ -88,6 +88,32 @@ export class LocalEnvironmentService extends EnvironmentService {
}); });
} }
private getScript(environment: EnvironmentInformation): string[] {
const script: string[] = [];
if (process.platform === 'win32') {
script.push(`cd $env:${this.experimentRootDir}`);
script.push(`New-Item -ItemType "directory" -Path ${path.join(this.experimentRootDir, 'envs', environment.id)} -Force`);
environment.command = `cd envs\\${environment.id} && python -m nni.tools.trial_tool.trial_runner`;
script.push(
`cmd.exe /c ${environment.command} --job_pid_file ${path.join(environment.runnerWorkingFolder, 'pid')} 2>&1 | Out-File "${path.join(environment.runnerWorkingFolder, 'trial_runner.log')}" -encoding utf8`,
`$NOW_DATE = [int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalSeconds`,
`$NOW_DATE = "$NOW_DATE" + (Get-Date -Format fff).ToString()`,
`Write $LASTEXITCODE " " $NOW_DATE | Out-File "${path.join(environment.runnerWorkingFolder, 'code')}" -NoNewline -encoding utf8`);
} else {
script.push(`cd ${this.experimentRootDir}`);
script.push(`eval ${environment.command} --job_pid_file ${environment.runnerWorkingFolder}/pid 1>${environment.runnerWorkingFolder}/trialrunner_stdout 2>${environment.runnerWorkingFolder}/trialrunner_stderr"`);
if (process.platform === 'darwin') {
// https://superuser.com/questions/599072/how-to-get-bash-execution-time-in-milliseconds-under-mac-os-x
// Considering the worst case, write 999 to avoid negative duration
script.push(`echo $? \`date +%s999\` >'${environment.runnerWorkingFolder}/code'`);
} else {
script.push(`echo $? \`date +%s%3N\` >'${environment.runnerWorkingFolder}/code'`);
}
}
return script;
}
public async startEnvironment(environment: EnvironmentInformation): Promise<void> { public async startEnvironment(environment: EnvironmentInformation): Promise<void> {
if (this.localTrialConfig === undefined) { if (this.localTrialConfig === undefined) {
throw new Error('Local trial config is not initialized'); throw new Error('Local trial config is not initialized');
...@@ -99,14 +125,13 @@ export class LocalEnvironmentService extends EnvironmentService { ...@@ -99,14 +125,13 @@ export class LocalEnvironmentService extends EnvironmentService {
environment.runnerWorkingFolder = path.join(localEnvCodeFolder, environment.id); environment.runnerWorkingFolder = path.join(localEnvCodeFolder, environment.id);
await execMkdir(environment.runnerWorkingFolder); await execMkdir(environment.runnerWorkingFolder);
await execCopydir(localTempFolder, localEnvCodeFolder); await execCopydir(localTempFolder, localEnvCodeFolder);
environment.command = `cd ${this.experimentRootDir} && \ environment.command = this.getScript(environment).join(getNewLine());
${environment.command} --job_pid_file ${environment.runnerWorkingFolder}/pid \ const scriptName: string = getScriptName('run');
1>${environment.runnerWorkingFolder}/trialrunner_stdout 2>${environment.runnerWorkingFolder}/trialrunner_stderr \ await fs.promises.writeFile(path.join(localEnvCodeFolder, scriptName),
&& echo $? \`date +%s%3N\` >${environment.runnerWorkingFolder}/code`; environment.command, { encoding: 'utf8', mode: 0o777 });
await fs.promises.writeFile(path.join(localEnvCodeFolder, 'nni_run.sh'),
environment.command, { encoding: 'utf8', mode: 0o777 }),
// Execute command in local machine // Execute command in local machine
runScript(path.join(localEnvCodeFolder, 'nni_run.sh')); runScript(path.join(localEnvCodeFolder, scriptName));
environment.trackingUrl = `${environment.runnerWorkingFolder}`; environment.trackingUrl = `${environment.runnerWorkingFolder}`;
} }
...@@ -115,7 +140,7 @@ ${environment.command} --job_pid_file ${environment.runnerWorkingFolder}/pid \ ...@@ -115,7 +140,7 @@ ${environment.command} --job_pid_file ${environment.runnerWorkingFolder}/pid \
return Promise.resolve(); return Promise.resolve();
} }
const jobpidPath: string = `${environment.runnerWorkingFolder}/pid`; const jobpidPath: string = `${path.join(environment.runnerWorkingFolder, 'pid')}`;
const pid: string = await fs.promises.readFile(jobpidPath, 'utf8'); const pid: string = await fs.promises.readFile(jobpidPath, 'utf8');
tkill(Number(pid), 'SIGKILL'); tkill(Number(pid), 'SIGKILL');
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment