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