summaryrefslogtreecommitdiff
path: root/libc/utils/gpu/loader/Main.cpp
blob: b711ec91c9f304404eb69f41074fada8055a6833 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//===-- Main entry into the loader interface ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file opens a device image passed on the command line and passes it to
// one of the loader implementations for launch.
//
//===----------------------------------------------------------------------===//

#include "Loader.h"

#include <cstdio>
#include <cstdlib>
#include <string>
#include <vector>

int main(int argc, char **argv, char **envp) {
  if (argc < 2) {
    printf("USAGE: ./loader [--threads <n>, --blocks <n>] <device_image> "
           "<args>, ...\n");
    return EXIT_SUCCESS;
  }

  int offset = 0;
  FILE *file = nullptr;
  char *ptr;
  LaunchParameters params = {1, 1, 1, 1, 1, 1};
  while (!file && ++offset < argc) {
    if (argv[offset] == std::string("--threads") ||
        argv[offset] == std::string("--threads-x")) {
      params.num_threads_x =
          offset + 1 < argc ? strtoul(argv[offset + 1], &ptr, 10) : 1;
      offset++;
      continue;
    } else if (argv[offset] == std::string("--threads-y")) {
      params.num_threads_y =
          offset + 1 < argc ? strtoul(argv[offset + 1], &ptr, 10) : 1;
      offset++;
      continue;
    } else if (argv[offset] == std::string("--threads-z")) {
      params.num_threads_z =
          offset + 1 < argc ? strtoul(argv[offset + 1], &ptr, 10) : 1;
      offset++;
      continue;
    } else if (argv[offset] == std::string("--blocks") ||
               argv[offset] == std::string("--blocks-x")) {
      params.num_blocks_x =
          offset + 1 < argc ? strtoul(argv[offset + 1], &ptr, 10) : 1;
      offset++;
      continue;
    } else if (argv[offset] == std::string("--blocks-y")) {
      params.num_blocks_y =
          offset + 1 < argc ? strtoul(argv[offset + 1], &ptr, 10) : 1;
      offset++;
      continue;
    } else if (argv[offset] == std::string("--blocks-z")) {
      params.num_blocks_z =
          offset + 1 < argc ? strtoul(argv[offset + 1], &ptr, 10) : 1;
      offset++;
      continue;
    } else {
      file = fopen(argv[offset], "r");
      if (!file) {
        fprintf(stderr, "Failed to open image file '%s'\n", argv[offset]);
        return EXIT_FAILURE;
      }
      break;
    }
  }

  if (!file) {
    fprintf(stderr, "No image file provided\n");
    return EXIT_FAILURE;
  }

  // TODO: We should perform some validation on the file.
  fseek(file, 0, SEEK_END);
  const auto size = ftell(file);
  fseek(file, 0, SEEK_SET);

  void *image = malloc(size * sizeof(char));
  fread(image, sizeof(char), size, file);
  fclose(file);

  // Drop the loader from the program arguments.
  int ret = load(argc - offset, &argv[offset], envp, image, size, params);

  free(image);
  return ret;
}