main.ts 5.14 KB
Newer Older
liuzhe-lz's avatar
liuzhe-lz committed
1
2
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
Deshui Yu's avatar
Deshui Yu committed
3

4
import 'app-module-path/register';
Deshui Yu's avatar
Deshui Yu committed
5
6
import { Container, Scope } from 'typescript-ioc';

7
import * as fs from 'fs';
8
import * as path from 'path';
9
import * as component from './common/component';
Deshui Yu's avatar
Deshui Yu committed
10
11
import { Database, DataStore } from './common/datastore';
import { setExperimentStartupInfo } from './common/experimentStartupInfo';
12
import { getLogger, setLogLevel, startLogging } from './common/log';
SparkSnail's avatar
SparkSnail committed
13
import { Manager, ExperimentStartUpMode } from './common/manager';
14
import { ExperimentManager } from './common/experimentManager';
J-shang's avatar
J-shang committed
15
import { TensorboardManager } from './common/tensorboardManager';
16
import { getLogDir, mkDirP, parseArg } from './common/utils';
Deshui Yu's avatar
Deshui Yu committed
17
18
19
import { NNIDataStore } from './core/nniDataStore';
import { NNIManager } from './core/nnimanager';
import { SqlDB } from './core/sqlDatabase';
20
import { NNIExperimentsManager } from './core/nniExperimentsManager';
J-shang's avatar
J-shang committed
21
import { NNITensorboardManager } from './core/nniTensorboardManager';
liuzhe-lz's avatar
liuzhe-lz committed
22
import { RestServer } from './rest_server';
23

24
function initStartupInfo(
25
    startExpMode: string, experimentId: string, basePort: number, platform: string,
26
    logDirectory: string, experimentLogLevel: string, readonly: boolean, dispatcherPipe: string, urlprefix: string): void {
SparkSnail's avatar
SparkSnail committed
27
    const createNew: boolean = (startExpMode === ExperimentStartUpMode.NEW);
28
    setExperimentStartupInfo(createNew, experimentId, basePort, platform, logDirectory, experimentLogLevel, readonly, dispatcherPipe, urlprefix);
Deshui Yu's avatar
Deshui Yu committed
29
30
}

31
async function initContainer(foreground: boolean, _platformMode: string, logFileName?: string): Promise<void> {
32
33
34
35
36
37
38
39
40
    Container.bind(Manager)
        .to(NNIManager)
        .scope(Scope.Singleton);
    Container.bind(Database)
        .to(SqlDB)
        .scope(Scope.Singleton);
    Container.bind(DataStore)
        .to(NNIDataStore)
        .scope(Scope.Singleton);
41
42
43
    Container.bind(ExperimentManager)
        .to(NNIExperimentsManager)
        .scope(Scope.Singleton);
J-shang's avatar
J-shang committed
44
45
46
    Container.bind(TensorboardManager)
        .to(NNITensorboardManager)
        .scope(Scope.Singleton);
47
    const DEFAULT_LOGFILE: string = path.join(getLogDir(), 'nnimanager.log');
48
49
50
51
52
53
    if (!foreground) {
        if (logFileName === undefined) {
            startLogging(DEFAULT_LOGFILE);
        } else {
            startLogging(logFileName);
        }
54
    }
J-shang's avatar
J-shang committed
55
56
    // eslint-disable-next-line @typescript-eslint/no-use-before-define
    setLogLevel(logLevel);
Deshui Yu's avatar
Deshui Yu committed
57
58
59
60
61
62
    const ds: DataStore = component.get(DataStore);

    await ds.init();
}

function usage(): void {
63
    console.info('usage: node main.js --port <port> --mode \
64
    <local/remote/pai/kubeflow/frameworkcontroller/aml/adl/hybrid/dlc> --start_mode <new/resume> --experiment_id <id> --foreground <true/false>');
Deshui Yu's avatar
Deshui Yu committed
65
66
67
}

const strPort: string = parseArg(['--port', '-p']);
goooxu's avatar
goooxu committed
68
69
70
if (!strPort || strPort.length === 0) {
    usage();
    process.exit(1);
Deshui Yu's avatar
Deshui Yu committed
71
72
}

73
const foregroundArg: string = parseArg(['--foreground', '-f']);
liuzhe-lz's avatar
liuzhe-lz committed
74
if (foregroundArg && !['true', 'false'].includes(foregroundArg.toLowerCase())) {
75
76
77
78
    console.log(`FATAL: foreground property should only be true or false`);
    usage();
    process.exit(1);
}
liuzhe-lz's avatar
liuzhe-lz committed
79
const foreground: boolean = (foregroundArg && foregroundArg.toLowerCase() === 'true') ? true : false;
80

goooxu's avatar
goooxu committed
81
82
const port: number = parseInt(strPort, 10);

Deshui Yu's avatar
Deshui Yu committed
83
84
85
const mode: string = parseArg(['--mode', '-m']);

const startMode: string = parseArg(['--start_mode', '-s']);
SparkSnail's avatar
SparkSnail committed
86
if (![ExperimentStartUpMode.NEW, ExperimentStartUpMode.RESUME].includes(startMode)) {
87
    console.log(`FATAL: unknown start_mode: ${startMode}`);
Deshui Yu's avatar
Deshui Yu committed
88
89
90
91
92
    usage();
    process.exit(1);
}

const experimentId: string = parseArg(['--experiment_id', '-id']);
93
if (experimentId.trim().length < 1) {
SparkSnail's avatar
SparkSnail committed
94
    console.log(`FATAL: cannot resume the experiment, invalid experiment_id: ${experimentId}`);
Deshui Yu's avatar
Deshui Yu committed
95
96
97
98
    usage();
    process.exit(1);
}

99
100
101
102
103
104
105
106
107
const logDir: string = parseArg(['--log_dir', '-ld']);
if (logDir.length > 0) {
    if (!fs.existsSync(logDir)) {
        console.log(`FATAL: log_dir ${logDir} does not exist`);
    }
}

const logLevel: string = parseArg(['--log_level', '-ll']);

SparkSnail's avatar
SparkSnail committed
108
const readonlyArg: string = parseArg(['--readonly', '-r']);
liuzhe-lz's avatar
liuzhe-lz committed
109
if (readonlyArg && !['true', 'false'].includes(readonlyArg.toLowerCase())) {
SparkSnail's avatar
SparkSnail committed
110
111
112
113
    console.log(`FATAL: readonly property should only be true or false`);
    usage();
    process.exit(1);
}
liuzhe-lz's avatar
liuzhe-lz committed
114
const readonly = (readonlyArg && readonlyArg.toLowerCase() == 'true') ? true : false;
SparkSnail's avatar
SparkSnail committed
115

116
117
const dispatcherPipe: string = parseArg(['--dispatcher_pipe']);

118
119
120
const urlPrefix: string = parseArg(['--url_prefix']);

initStartupInfo(startMode, experimentId, port, mode, logDir, logLevel, readonly, dispatcherPipe, urlPrefix);
Deshui Yu's avatar
Deshui Yu committed
121

122
123
mkDirP(getLogDir())
    .then(async () => {
124
125
        try {
            await initContainer(foreground, mode);
liuzhe-lz's avatar
liuzhe-lz committed
126
            const restServer: RestServer = component.get(RestServer);
127
128
            await restServer.start();
        } catch (err) {
129
            getLogger('main').error(`${err.stack}`);
130
131
132
133
134
135
            throw err;
        }
    })
    .catch((err: Error) => {
        console.error(`Failed to create log dir: ${err.stack}`);
    });
136

137
138
function cleanUp(): void {
    (component.get(Manager) as Manager).stopExperiment();
139
140
141
142
143
}

process.on('SIGTERM', cleanUp);
process.on('SIGBREAK', cleanUp);
process.on('SIGINT', cleanUp);