当前位置:   article > 正文

tritonserver学习之四:命令行解析_triton server

triton server

tritonserver学习之一:triton使用流程

tritonserver学习之二:tritonserver编译

tritonserver学习之三:tritonserver运行流程

tritonserver学习之五:backend实现机制

tritonserver学习之六:自定义c++、python custom backend实践

tritonserver学习之七:cache管理器

tritonserver学习之八:redis_caches实践

tritonserver学习之九:tritonserver grpc异步模式

1、命令行解析的两个函数

1.1 getopt

int getopt(intargc, char * const argv[], const char *optstring);

getopt用来解析命令行参数,但是只能解析短选项,例如:-b 100,不能解析长选项--prefix。

参数说明:

  1. argc:main()函数传递过来的参数的个数
  2. argv:main()函数传递过来的参数的字符串指针数组
  3. optstring:选项字符串,告知 getopt()可以处理哪个选项以及哪个选项需要参数

重点说明optstring字段:

  1. char *optstring = “ab:c::”;
  2. 单个字符a 表示选项a没有参数 格式:-a即可,不加参数
  3. 单字符加冒号b: 表示选项b有且必须加参数 格式:-b 100或-b100, -b=100这种格式是错误的
  4. 单字符加2个冒号c:: 表示选项c可以有,也可以无 格式:-c200,其它格式错误

函数返回值:

  1. 如果选项成功找到,返回选项字母;
  2. 如果所有命令行选项都解析完毕,返回 -1
  3. 如果遇到选项字符不在 optstring 中,返回字符 '?'
  4. 如果遇到丢失参数,那么返回值依赖于 optstring 中第一个字符,如果第一个字符是 ':' 则返回':'
  5. 否则返回'?'并提示出错误信息。

几个重要的全局变量:

  1. optarg —— 指向当前选项参数(如果有)的指针。
  2. optind —— 再次调用 getopt() 时的下一个 argv指针的索引。
  3. optopt —— 最后一个未知选项。
  4. opterr ­—— 如果不希望getopt()打印出错信息,则只要将全域变量opterr设为0即可。

示例:

  1. #include <iostream>
  2. #include <thread>
  3. #include<getopt.h>
  4. int main(int argc, char *argv[])
  5. {
  6. unsigned int n = std::thread::hardware_concurrency();
  7. std::cout << " concurrent threads are supported = " << n << std::endl;
  8. int opt;
  9. std::string str = "a::b:c:d";
  10. while ((opt = getopt(argc, argv, str.data()))!= -1)
  11. {
  12. printf("opt = %c\t\t", opt);
  13. printf("optarg = %s\t\t",optarg);
  14. printf("optind = %d\t\t",optind);
  15. printf("argv[optind] = %s\n",argv[optind]);
  16. }
  17. }

运行结果:

  1. liupeng@liupengdeMacBook-Pro Downloads % ./a.out -a100 -b 200 -c200 -d
  2. concurrent threads are supported = 8
  3. opt = a optarg = 100 optind = 2 argv[optind] = -b
  4. opt = b optarg = 200 optind = 4 argv[optind] = -c200
  5. opt = c optarg = 200 optind = 5 argv[optind] = -d
  6. opt = d optarg = (null) optind = 6 argv[optind] = (null)

选项a是可选参数,可以不带参数。

1.2 getopt_long

triton中使用的是该函数,getopt_long包含了getopt函数的所有功能,并且可以指定长选项。

  1. int getopt_long(int argc, char * const argv[], const char *optstring,
  2. const struct option *longopts, int*longindex);

参数说明:

  1. longopts 指明了长参数的名称和属性
  2. longindex 如果longindex非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述,即是longopts的下标值

struct option结构体:

  1. struct option {
  2. const char *name; /* 参数名称 */
  3. int has_arg; /* 指明是否带有参数 */
  4. int *flag; /* flag=NULL时,返回val;不为空时,*flag=val,返回0 */
  5. int val; /* 用于指定函数找到选项的返回值或flag非空时指定*flag的值 */
  6. };

函数返回值:

  1. 对于短选项,返回值同getopt函数;对于长选项,如果flag是NULL,返回val,否则返回0
  2. 对于错误情况返回值同getopt函数

has_arg参数说明: 

  1. has_arg 指明是否带参数值,其数值可选:
  2. no_argument 表明长选项不带参数,如:--name, --help
  3. required_argument 表明长选项必须带参数,如:--prefix /root或 --prefix=/root
  4. optional_argument 表明长选项的参数是可选的,如:--help或 –prefix=/root,其它都是错误

代码示例:

  1. #include <iostream>
  2. #include <thread>
  3. #include <getopt.h>
  4. int main(int argc, char *argv[])
  5. {
  6. unsigned int n = std::thread::hardware_concurrency();
  7. std::cout << " concurrent threads are supported = " << n << std::endl;
  8. int opt;
  9. std::string str = "a::b:c:d";
  10. static struct option long_options[] =
  11. {
  12. {"reqarg", required_argument,NULL, 'r'},
  13. {"optarg", optional_argument,NULL, 'o'},
  14. {"noarg", no_argument, NULL,'n'},
  15. {NULL, 0, NULL, 0},
  16. };
  17. int option_index;
  18. while((opt =getopt_long(argc,argv,str.data(),long_options,&option_index))!= -1)
  19. {
  20. printf("opt = %c\t\t", opt);
  21. printf("optarg = %s\t\t",optarg);
  22. printf("optind = %d\t\t",optind);
  23. printf("argv[optind] =%s\t\t", argv[optind]);
  24. printf("option_index = %d\n",option_index);
  25. }
  26. }

运行结果:

  1. liupeng@liupengdeMacBook-Pro Downloads % ./a.out -b 200 -d --reqarg 100 --optarg 200
  2. concurrent threads are supported = 8
  3. opt = b optarg = 200 optind = 3 argv[optind] =-d option_index = 1
  4. opt = d optarg = (null) optind = 4 argv[optind] =--reqarg option_index = 1
  5. opt = r optarg = 100 optind = 6 argv[optind] =--optarg option_index = 0
  6. opt = o optarg = (null) optind = 7 argv[optind] =200 option_index = 1
  7. liupeng@liupengdeMacBook-Pro Downloads %

2、triton命令行处理

tritonserver版本为当前最新:2.36.0

2.1 TritonParser类-命令注册

TritonParser类的构造函数,实现了支持的命令行的注册。

构造函数位于:command_line_parser.cc文件的L814,构造函数调用了SetupOptionGroups()函数。

  1. void
  2. TritonParser::SetupOptionGroups()
  3. {
  4. SetupOptions();
  5. option_groups_.emplace_back(GLOBAL_OPTION_GROUP, global_options_);
  6. option_groups_.emplace_back("Server", server_options_);
  7. option_groups_.emplace_back("Logging", logging_options_);
  8. option_groups_.emplace_back("Model Repository", model_repo_options_);
  9. option_groups_.emplace_back("HTTP", http_options_);
  10. option_groups_.emplace_back("GRPC", grpc_options_);
  11. option_groups_.emplace_back("Sagemaker", sagemaker_options_);
  12. option_groups_.emplace_back("Vertex", vertex_options_);
  13. option_groups_.emplace_back("Metrics", metric_options_);
  14. option_groups_.emplace_back("Tracing", tracing_options_);
  15. option_groups_.emplace_back("Backend", backend_options_);
  16. option_groups_.emplace_back("Repository Agent", repo_agent_options_);
  17. option_groups_.emplace_back("Response Cache", cache_options_);
  18. option_groups_.emplace_back("Rate Limiter", rate_limiter_options_);
  19. option_groups_.emplace_back(
  20. "Memory/Device Management", memory_device_options_);
  21. option_groups_.emplace_back("DEPRECATED", deprecated_options_);
  22. }

具体实现:

  1. void
  2. TritonParser::SetupOptions()
  3. {
  4. global_options_.push_back(
  5. {OPTION_HELP, "help", Option::ArgNone, "Print usage"});
  6. server_options_.push_back(
  7. {OPTION_ID, "id", Option::ArgStr, "Identifier for this server."});
  8. server_options_.push_back(
  9. {OPTION_EXIT_TIMEOUT_SECS, "exit-timeout-secs", Option::ArgInt,
  10. "Timeout (in seconds) when exiting to wait for in-flight inferences to "
  11. "finish. After the timeout expires the server exits even if inferences "
  12. "are still in flight."});
  13. }

global_options_、server_options_的定义如下:

  1. std::vector<Option> global_options_;
  2. std::vector<Option> server_options_;

其中,Option为命令行的结构体:

  1. // Command-line options
  2. struct Option {
  3. static constexpr const char* ArgNone = "";
  4. static constexpr const char* ArgBool = "boolean";
  5. static constexpr const char* ArgFloat = "float";
  6. static constexpr const char* ArgInt = "integer";
  7. static constexpr const char* ArgStr = "string";
  8. Option(int id, std::string flag, std::string arg_desc, std::string desc)
  9. : id_(id), flag_(flag), arg_desc_(arg_desc), desc_(desc)
  10. {
  11. }
  12. struct option GetLongOption() const
  13. {
  14. struct option lo {
  15. flag_.c_str(), (!arg_desc_.empty()) ? required_argument : no_argument,
  16. nullptr, id_
  17. };
  18. return lo;
  19. }
  20. const int id_;
  21. const std::string flag_;
  22. const std::string arg_desc_;
  23. const std::string desc_;
  24. };

该结构共4个字段,用于对命令行进行描述,GetLongOption函数完成triton Option到系统struct option结构的转换,到此,命令行完成注册,所有支持的命令行全部保存到了option_groups_,这个vector中。

2.2 TritonParser类-命令解析

命令行解析函数:

  1. std::pair<TritonServerParameters, std::vector<char*>>
  2. TritonParser::Parse(int argc, char** argv)

triton中解析命令行设计的方案就是使用getopt_long函数,因此第一步是将支持的命令行完成从triton系统中Option结构到系统struct option结构的转换:

  1. std::vector<struct option> long_options;
  2. for (const auto& group : option_groups_) {
  3. for (const auto& o : group.second) {
  4. long_options.push_back(o.GetLongOption());
  5. }
  6. }
  7. long_options.push_back({nullptr, 0, nullptr, 0});

这几行代码位于:command_line_parser.cc文件的L1167,接下来就是使用getopt_long函数,循环对命令行进行解析,解析的命令行参数值,全部放在了结构体lparams这个TritonServerParameters结构体变量中。

3、main函数中调用

  1. int
  2. main(int argc, char** argv)
  3. {
  4. // Parse command-line to create the options for the inference
  5. // server.
  6. triton::server::TritonParser tp;
  7. try {
  8. auto res = tp.Parse(argc, argv);
  9. g_triton_params = res.first;
  10. g_triton_params.CheckPortCollision();
  11. }
  12. catch (const triton::server::ParseException& pe) {
  13. std::cerr << pe.what() << std::endl;
  14. std::cerr << "Usage: tritonserver [options]" << std::endl;
  15. std::cerr << tp.Usage() << std::endl;
  16. exit(1);
  17. }
  18. .........
  19. }

代码走到g_triton_params = res.first;这一行,就已经获取到了用户输入的所有参数值,当获取到所有参数之后,调用了TritonServerParameters结构成员函数:g_triton_params.BuildTritonServerOptions(),将这些参数设置到TritonServerOptions这个核心类成员中。

以上就是triton命令行注册、解析部分,希望能帮到各位正在学习triton的同学。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/351785
推荐阅读
相关标签
  

闽ICP备14008679号