xref: /llvm-project/libc/utils/gpu/loader/Main.cpp (revision 1ecffdaf27cb456aecc5a1c0272d3994d26bf645)
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("USAGE: ./loader [--threads <n>, --blocks <n>, "
24            "--print-resource-usage] <device_image> "
25            "<args>, ...\n");
26     return EXIT_SUCCESS;
27   }
28 
29   int offset = 0;
30   FILE *file = nullptr;
31   char *ptr;
32   LaunchParameters params = {1, 1, 1, 1, 1, 1};
33   bool print_resource_usage = false;
34   while (!file && ++offset < argc) {
35     if (argv[offset] == std::string("--threads") ||
36         argv[offset] == std::string("--threads-x")) {
37       params.num_threads_x =
38           offset + 1 < argc ? strtoul(argv[offset + 1], &ptr, 10) : 1;
39       offset++;
40       continue;
41     } else if (argv[offset] == std::string("--threads-y")) {
42       params.num_threads_y =
43           offset + 1 < argc ? strtoul(argv[offset + 1], &ptr, 10) : 1;
44       offset++;
45       continue;
46     } else if (argv[offset] == std::string("--threads-z")) {
47       params.num_threads_z =
48           offset + 1 < argc ? strtoul(argv[offset + 1], &ptr, 10) : 1;
49       offset++;
50       continue;
51     } else if (argv[offset] == std::string("--blocks") ||
52                argv[offset] == std::string("--blocks-x")) {
53       params.num_blocks_x =
54           offset + 1 < argc ? strtoul(argv[offset + 1], &ptr, 10) : 1;
55       offset++;
56       continue;
57     } else if (argv[offset] == std::string("--blocks-y")) {
58       params.num_blocks_y =
59           offset + 1 < argc ? strtoul(argv[offset + 1], &ptr, 10) : 1;
60       offset++;
61       continue;
62     } else if (argv[offset] == std::string("--blocks-z")) {
63       params.num_blocks_z =
64           offset + 1 < argc ? strtoul(argv[offset + 1], &ptr, 10) : 1;
65       offset++;
66       continue;
67     } else if (argv[offset] == std::string("--print-resource-usage")) {
68       print_resource_usage = true;
69       continue;
70     } else {
71       file = fopen(argv[offset], "r");
72       if (!file) {
73         fprintf(stderr, "Failed to open image file '%s'\n", argv[offset]);
74         return EXIT_FAILURE;
75       }
76       break;
77     }
78   }
79 
80   if (!file) {
81     fprintf(stderr, "No image file provided\n");
82     return EXIT_FAILURE;
83   }
84 
85   // TODO: We should perform some validation on the file.
86   fseek(file, 0, SEEK_END);
87   const auto size = ftell(file);
88   fseek(file, 0, SEEK_SET);
89 
90   void *image = malloc(size * sizeof(char));
91   fread(image, sizeof(char), size, file);
92   fclose(file);
93 
94   // Drop the loader from the program arguments.
95   int ret = load(argc - offset, &argv[offset], envp, image, size, params,
96                  print_resource_usage);
97 
98   free(image);
99   return ret;
100 }
101