赞
踩
tritonserver学习之二:tritonserver编译
tritonserver学习之三:tritonserver运行流程
tritonserver学习之六:自定义c++、python custom backend实践
tritonserver学习之八:redis_caches实践
tritonserver学习之九:tritonserver grpc异步模式
int getopt(intargc, char * const argv[], const char *optstring);
getopt用来解析命令行参数,但是只能解析短选项,例如:-b 100,不能解析长选项--prefix。
参数说明:
- argc:main()函数传递过来的参数的个数
- argv:main()函数传递过来的参数的字符串指针数组
- optstring:选项字符串,告知 getopt()可以处理哪个选项以及哪个选项需要参数
重点说明optstring字段:
- char *optstring = “ab:c::”;
- 单个字符a 表示选项a没有参数 格式:-a即可,不加参数
- 单字符加冒号b: 表示选项b有且必须加参数 格式:-b 100或-b100, -b=100这种格式是错误的
- 单字符加2个冒号c:: 表示选项c可以有,也可以无 格式:-c200,其它格式错误
函数返回值:
- 如果选项成功找到,返回选项字母;
- 如果所有命令行选项都解析完毕,返回 -1;
- 如果遇到选项字符不在 optstring 中,返回字符 '?';
- 如果遇到丢失参数,那么返回值依赖于 optstring 中第一个字符,如果第一个字符是 ':' 则返回':',
- 否则返回'?'并提示出错误信息。
几个重要的全局变量:
- optarg —— 指向当前选项参数(如果有)的指针。
- optind —— 再次调用 getopt() 时的下一个 argv指针的索引。
- optopt —— 最后一个未知选项。
- opterr —— 如果不希望getopt()打印出错信息,则只要将全域变量opterr设为0即可。
示例:
- #include <iostream>
- #include <thread>
- #include<getopt.h>
-
- int main(int argc, char *argv[])
- {
- unsigned int n = std::thread::hardware_concurrency();
- std::cout << " concurrent threads are supported = " << n << std::endl;
- int opt;
- std::string str = "a::b:c:d";
- while ((opt = getopt(argc, argv, str.data()))!= -1)
- {
- printf("opt = %c\t\t", opt);
- printf("optarg = %s\t\t",optarg);
- printf("optind = %d\t\t",optind);
- printf("argv[optind] = %s\n",argv[optind]);
- }
- }
运行结果:
- liupeng@liupengdeMacBook-Pro Downloads % ./a.out -a100 -b 200 -c200 -d
- concurrent threads are supported = 8
- opt = a optarg = 100 optind = 2 argv[optind] = -b
- opt = b optarg = 200 optind = 4 argv[optind] = -c200
- opt = c optarg = 200 optind = 5 argv[optind] = -d
- opt = d optarg = (null) optind = 6 argv[optind] = (null)
选项a是可选参数,可以不带参数。
triton中使用的是该函数,getopt_long包含了getopt函数的所有功能,并且可以指定长选项。
- int getopt_long(int argc, char * const argv[], const char *optstring,
- const struct option *longopts, int*longindex);
参数说明:
- longopts 指明了长参数的名称和属性
- longindex 如果longindex非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述,即是longopts的下标值
struct option结构体:
- struct option {
- const char *name; /* 参数名称 */
- int has_arg; /* 指明是否带有参数 */
- int *flag; /* flag=NULL时,返回val;不为空时,*flag=val,返回0 */
- int val; /* 用于指定函数找到选项的返回值或flag非空时指定*flag的值 */
- };
函数返回值:
- 对于短选项,返回值同getopt函数;对于长选项,如果flag是NULL,返回val,否则返回0;
- 对于错误情况返回值同getopt函数
has_arg参数说明:
- has_arg 指明是否带参数值,其数值可选:
- no_argument 表明长选项不带参数,如:--name, --help
- required_argument 表明长选项必须带参数,如:--prefix /root或 --prefix=/root
- optional_argument 表明长选项的参数是可选的,如:--help或 –prefix=/root,其它都是错误
代码示例:
- #include <iostream>
- #include <thread>
- #include <getopt.h>
-
- int main(int argc, char *argv[])
- {
- unsigned int n = std::thread::hardware_concurrency();
- std::cout << " concurrent threads are supported = " << n << std::endl;
- int opt;
- std::string str = "a::b:c:d";
- static struct option long_options[] =
- {
- {"reqarg", required_argument,NULL, 'r'},
- {"optarg", optional_argument,NULL, 'o'},
- {"noarg", no_argument, NULL,'n'},
- {NULL, 0, NULL, 0},
- };
- int option_index;
- while((opt =getopt_long(argc,argv,str.data(),long_options,&option_index))!= -1)
- {
- printf("opt = %c\t\t", opt);
- printf("optarg = %s\t\t",optarg);
- printf("optind = %d\t\t",optind);
- printf("argv[optind] =%s\t\t", argv[optind]);
- printf("option_index = %d\n",option_index);
- }
- }
运行结果:
- liupeng@liupengdeMacBook-Pro Downloads % ./a.out -b 200 -d --reqarg 100 --optarg 200
- concurrent threads are supported = 8
- opt = b optarg = 200 optind = 3 argv[optind] =-d option_index = 1
- opt = d optarg = (null) optind = 4 argv[optind] =--reqarg option_index = 1
- opt = r optarg = 100 optind = 6 argv[optind] =--optarg option_index = 0
- opt = o optarg = (null) optind = 7 argv[optind] =200 option_index = 1
- liupeng@liupengdeMacBook-Pro Downloads %
tritonserver版本为当前最新:2.36.0
TritonParser类的构造函数,实现了支持的命令行的注册。
构造函数位于:command_line_parser.cc文件的L814,构造函数调用了SetupOptionGroups()函数。
- void
- TritonParser::SetupOptionGroups()
- {
- SetupOptions();
- option_groups_.emplace_back(GLOBAL_OPTION_GROUP, global_options_);
- option_groups_.emplace_back("Server", server_options_);
- option_groups_.emplace_back("Logging", logging_options_);
- option_groups_.emplace_back("Model Repository", model_repo_options_);
- option_groups_.emplace_back("HTTP", http_options_);
- option_groups_.emplace_back("GRPC", grpc_options_);
- option_groups_.emplace_back("Sagemaker", sagemaker_options_);
- option_groups_.emplace_back("Vertex", vertex_options_);
- option_groups_.emplace_back("Metrics", metric_options_);
- option_groups_.emplace_back("Tracing", tracing_options_);
- option_groups_.emplace_back("Backend", backend_options_);
- option_groups_.emplace_back("Repository Agent", repo_agent_options_);
- option_groups_.emplace_back("Response Cache", cache_options_);
- option_groups_.emplace_back("Rate Limiter", rate_limiter_options_);
- option_groups_.emplace_back(
- "Memory/Device Management", memory_device_options_);
- option_groups_.emplace_back("DEPRECATED", deprecated_options_);
- }
具体实现:
- void
- TritonParser::SetupOptions()
- {
- global_options_.push_back(
- {OPTION_HELP, "help", Option::ArgNone, "Print usage"});
-
- server_options_.push_back(
- {OPTION_ID, "id", Option::ArgStr, "Identifier for this server."});
- server_options_.push_back(
- {OPTION_EXIT_TIMEOUT_SECS, "exit-timeout-secs", Option::ArgInt,
- "Timeout (in seconds) when exiting to wait for in-flight inferences to "
- "finish. After the timeout expires the server exits even if inferences "
- "are still in flight."});
-
- }
global_options_、server_options_的定义如下:
- std::vector<Option> global_options_;
- std::vector<Option> server_options_;
其中,Option为命令行的结构体:
- // Command-line options
- struct Option {
- static constexpr const char* ArgNone = "";
- static constexpr const char* ArgBool = "boolean";
- static constexpr const char* ArgFloat = "float";
- static constexpr const char* ArgInt = "integer";
- static constexpr const char* ArgStr = "string";
-
- Option(int id, std::string flag, std::string arg_desc, std::string desc)
- : id_(id), flag_(flag), arg_desc_(arg_desc), desc_(desc)
- {
- }
-
- struct option GetLongOption() const
- {
- struct option lo {
- flag_.c_str(), (!arg_desc_.empty()) ? required_argument : no_argument,
- nullptr, id_
- };
- return lo;
- }
-
- const int id_;
- const std::string flag_;
- const std::string arg_desc_;
- const std::string desc_;
- };
该结构共4个字段,用于对命令行进行描述,GetLongOption函数完成triton Option到系统struct option结构的转换,到此,命令行完成注册,所有支持的命令行全部保存到了option_groups_,这个vector中。
命令行解析函数:
- std::pair<TritonServerParameters, std::vector<char*>>
- TritonParser::Parse(int argc, char** argv)
triton中解析命令行设计的方案就是使用getopt_long函数,因此第一步是将支持的命令行完成从triton系统中Option结构到系统struct option结构的转换:
- std::vector<struct option> long_options;
- for (const auto& group : option_groups_) {
- for (const auto& o : group.second) {
- long_options.push_back(o.GetLongOption());
- }
- }
- long_options.push_back({nullptr, 0, nullptr, 0});
这几行代码位于:command_line_parser.cc文件的L1167,接下来就是使用getopt_long函数,循环对命令行进行解析,解析的命令行参数值,全部放在了结构体lparams这个TritonServerParameters结构体变量中。
- int
- main(int argc, char** argv)
- {
- // Parse command-line to create the options for the inference
- // server.
- triton::server::TritonParser tp;
- try {
- auto res = tp.Parse(argc, argv);
- g_triton_params = res.first;
- g_triton_params.CheckPortCollision();
- }
- catch (const triton::server::ParseException& pe) {
- std::cerr << pe.what() << std::endl;
- std::cerr << "Usage: tritonserver [options]" << std::endl;
- std::cerr << tp.Usage() << std::endl;
- exit(1);
- }
-
- .........
-
- }
代码走到g_triton_params = res.first;这一行,就已经获取到了用户输入的所有参数值,当获取到所有参数之后,调用了TritonServerParameters结构成员函数:g_triton_params.BuildTritonServerOptions(),将这些参数设置到TritonServerOptions这个核心类成员中。
以上就是triton命令行注册、解析部分,希望能帮到各位正在学习triton的同学。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。