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
21int 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

source code of libc/utils/gpu/loader/Main.cpp