1 | //===-- Main entry into the loader interface ------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file opens a device image passed on the command line and passes it to |
10 | // one of the loader implementations for launch. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "Loader.h" |
15 | |
16 | #include <cstdio> |
17 | #include <cstdlib> |
18 | #include <string> |
19 | #include <vector> |
20 | |
21 | int main(int argc, char **argv, char **envp) { |
22 | if (argc < 2) { |
23 | printf(format: "USAGE: ./loader [--threads <n>, --blocks <n>] <device_image> " |
24 | "<args>, ...\n" ); |
25 | return EXIT_SUCCESS; |
26 | } |
27 | |
28 | int offset = 0; |
29 | FILE *file = nullptr; |
30 | char *ptr; |
31 | LaunchParameters params = {.num_threads_x: 1, .num_threads_y: 1, .num_threads_z: 1, .num_blocks_x: 1, .num_blocks_y: 1, .num_blocks_z: 1}; |
32 | while (!file && ++offset < argc) { |
33 | if (argv[offset] == std::string("--threads" ) || |
34 | argv[offset] == std::string("--threads-x" )) { |
35 | params.num_threads_x = |
36 | offset + 1 < argc ? strtoul(nptr: argv[offset + 1], endptr: &ptr, base: 10) : 1; |
37 | offset++; |
38 | continue; |
39 | } else if (argv[offset] == std::string("--threads-y" )) { |
40 | params.num_threads_y = |
41 | offset + 1 < argc ? strtoul(nptr: argv[offset + 1], endptr: &ptr, base: 10) : 1; |
42 | offset++; |
43 | continue; |
44 | } else if (argv[offset] == std::string("--threads-z" )) { |
45 | params.num_threads_z = |
46 | offset + 1 < argc ? strtoul(nptr: argv[offset + 1], endptr: &ptr, base: 10) : 1; |
47 | offset++; |
48 | continue; |
49 | } else if (argv[offset] == std::string("--blocks" ) || |
50 | argv[offset] == std::string("--blocks-x" )) { |
51 | params.num_blocks_x = |
52 | offset + 1 < argc ? strtoul(nptr: argv[offset + 1], endptr: &ptr, base: 10) : 1; |
53 | offset++; |
54 | continue; |
55 | } else if (argv[offset] == std::string("--blocks-y" )) { |
56 | params.num_blocks_y = |
57 | offset + 1 < argc ? strtoul(nptr: argv[offset + 1], endptr: &ptr, base: 10) : 1; |
58 | offset++; |
59 | continue; |
60 | } else if (argv[offset] == std::string("--blocks-z" )) { |
61 | params.num_blocks_z = |
62 | offset + 1 < argc ? strtoul(nptr: argv[offset + 1], endptr: &ptr, base: 10) : 1; |
63 | offset++; |
64 | continue; |
65 | } else { |
66 | file = fopen(filename: argv[offset], modes: "r" ); |
67 | if (!file) { |
68 | fprintf(stderr, format: "Failed to open image file '%s'\n" , argv[offset]); |
69 | return EXIT_FAILURE; |
70 | } |
71 | break; |
72 | } |
73 | } |
74 | |
75 | if (!file) { |
76 | fprintf(stderr, format: "No image file provided\n" ); |
77 | return EXIT_FAILURE; |
78 | } |
79 | |
80 | // TODO: We should perform some validation on the file. |
81 | fseek(stream: file, off: 0, SEEK_END); |
82 | const auto size = ftell(stream: file); |
83 | fseek(stream: file, off: 0, SEEK_SET); |
84 | |
85 | void *image = malloc(size: size * sizeof(char)); |
86 | fread(ptr: image, size: sizeof(char), n: size, stream: file); |
87 | fclose(stream: file); |
88 | |
89 | // Drop the loader from the program arguments. |
90 | int ret = load(argc: argc - offset, argv: &argv[offset], evnp: envp, image, size, params); |
91 | |
92 | free(ptr: image); |
93 | return ret; |
94 | } |
95 | |