* [Intel-gfx] [PATCH i-g-t 0/3] More intel_gpu_top improvements
@ 2023-02-03 11:16 Tvrtko Ursulin
2023-02-03 11:16 ` [Intel-gfx] [PATCH i-g-t 1/3] intel_gpu_top: Do not repeat header lines in non-interactive output Tvrtko Ursulin
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Tvrtko Ursulin @ 2023-02-03 11:16 UTC (permalink / raw)
To: igt-dev, Intel-gfx
From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Suggestion was received to omit repeating header lines when outputting to a file
and also to add the CVS mode for easy parsing. We have JSON but I guess CVS can
definitely be easier for some use cases.
Tvrtko Ursulin (3):
intel_gpu_top: Do not repeat header lines in non-interactive output
intel_gpu_top: Rename STDOUT to TEXT
intel_gpu_top: Add CVS output format
man/intel_gpu_top.rst | 3 +
tools/intel_gpu_top.c | 137 +++++++++++++++++++++++++++++++++---------
2 files changed, 111 insertions(+), 29 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Intel-gfx] [PATCH i-g-t 1/3] intel_gpu_top: Do not repeat header lines in non-interactive output
2023-02-03 11:16 [Intel-gfx] [PATCH i-g-t 0/3] More intel_gpu_top improvements Tvrtko Ursulin
@ 2023-02-03 11:16 ` Tvrtko Ursulin
2023-02-07 13:25 ` Kamil Konieczny
2023-02-08 12:31 ` Kamil Konieczny
2023-02-03 11:16 ` [Intel-gfx] [PATCH i-g-t 2/3] intel_gpu_top: Rename STDOUT to TEXT Tvrtko Ursulin
2023-02-03 11:16 ` [Intel-gfx] [PATCH i-g-t 3/3] intel_gpu_top: Add CVS output format Tvrtko Ursulin
2 siblings, 2 replies; 13+ messages in thread
From: Tvrtko Ursulin @ 2023-02-03 11:16 UTC (permalink / raw)
To: igt-dev, Intel-gfx; +Cc: Caleb Callaway
From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
If output is redirected to a file, or a pipe, lets not repeat the headers
because that can usually mean user is trying to parse the data later and
so repeated headers are a hindrance.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Caleb Callaway <caleb.callaway@intel.com>
---
tools/intel_gpu_top.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
index 0a1de41b3374..e2a7f4753099 100644
--- a/tools/intel_gpu_top.c
+++ b/tools/intel_gpu_top.c
@@ -1391,6 +1391,7 @@ static unsigned int stdout_level;
#define STDOUT_HEADER_REPEAT 20
static unsigned int stdout_lines = STDOUT_HEADER_REPEAT;
+static bool stdout_header_repeat;
static void
stdout_open_struct(const char *name)
@@ -1580,16 +1581,22 @@ static const struct print_operations term_pops = {
static bool print_groups(struct cnt_group **groups)
{
- unsigned int headers = stdout_lines % STDOUT_HEADER_REPEAT + 1;
+ static bool headers_printed = false;
bool print_data = true;
- if (output_mode == STDOUT && (headers == 1 || headers == 2)) {
- for (struct cnt_group **grp = groups; *grp; grp++)
- print_data = pops->print_group(*grp, headers);
+ if (output_mode == STDOUT &&
+ (stdout_header_repeat || !headers_printed)) {
+ unsigned int headers = stdout_lines % STDOUT_HEADER_REPEAT + 1;
+
+ if (headers == 1 || headers == 2)
+ for (struct cnt_group **grp = groups; *grp; grp++)
+ print_data = pops->print_group(*grp, headers);
+
+ headers_printed = print_data;
}
for (struct cnt_group **grp = groups; print_data && *grp; grp++)
- pops->print_group(*grp, false);
+ pops->print_group(*grp, 0);
return print_data;
}
@@ -2512,6 +2519,8 @@ int main(int argc, char **argv)
out = stdout;
}
+ stdout_header_repeat = output_mode == STDOUT && isatty(fileno(out));
+
if (signal(SIGINT, sigint_handler) == SIG_ERR)
fprintf(stderr, "Failed to install signal handler!\n");
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Intel-gfx] [PATCH i-g-t 2/3] intel_gpu_top: Rename STDOUT to TEXT
2023-02-03 11:16 [Intel-gfx] [PATCH i-g-t 0/3] More intel_gpu_top improvements Tvrtko Ursulin
2023-02-03 11:16 ` [Intel-gfx] [PATCH i-g-t 1/3] intel_gpu_top: Do not repeat header lines in non-interactive output Tvrtko Ursulin
@ 2023-02-03 11:16 ` Tvrtko Ursulin
2023-02-07 13:15 ` [Intel-gfx] [igt-dev] " Kamil Konieczny
2023-02-03 11:16 ` [Intel-gfx] [PATCH i-g-t 3/3] intel_gpu_top: Add CVS output format Tvrtko Ursulin
2 siblings, 1 reply; 13+ messages in thread
From: Tvrtko Ursulin @ 2023-02-03 11:16 UTC (permalink / raw)
To: igt-dev, Intel-gfx; +Cc: Caleb Callaway
From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Internal cleanup only - the name text is more accurate given the output
can also go to a file.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Caleb Callaway <caleb.callaway@intel.com>
---
tools/intel_gpu_top.c | 54 +++++++++++++++++++++----------------------
1 file changed, 26 insertions(+), 28 deletions(-)
diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
index e2a7f4753099..a980cc7043dc 100644
--- a/tools/intel_gpu_top.c
+++ b/tools/intel_gpu_top.c
@@ -1282,7 +1282,7 @@ usage(const char *appname)
static enum {
INTERACTIVE,
- STDOUT,
+ TEXT,
JSON
} output_mode;
@@ -1387,33 +1387,31 @@ json_add_member(const struct cnt_group *parent, struct cnt_item *item,
return 1;
}
-static unsigned int stdout_level;
+static unsigned int text_level;
-#define STDOUT_HEADER_REPEAT 20
-static unsigned int stdout_lines = STDOUT_HEADER_REPEAT;
-static bool stdout_header_repeat;
+#define TEXT_HEADER_REPEAT 20
+static unsigned int text_lines = TEXT_HEADER_REPEAT;
+static bool text_header_repeat;
-static void
-stdout_open_struct(const char *name)
+static void text_open_struct(const char *name)
{
- stdout_level++;
- assert(stdout_level > 0);
+ text_level++;
+ assert(text_level > 0);
}
-static void
-stdout_close_struct(void)
+static void text_close_struct(void)
{
- assert(stdout_level > 0);
- if (--stdout_level == 0) {
- stdout_lines++;
+ assert(text_level > 0);
+ if (--text_level == 0) {
+ text_lines++;
fputs("\n", out);
fflush(out);
}
}
static unsigned int
-stdout_add_member(const struct cnt_group *parent, struct cnt_item *item,
- unsigned int headers)
+text_add_member(const struct cnt_group *parent, struct cnt_item *item,
+ unsigned int headers)
{
unsigned int fmt_tot = item->fmt_width + (item->fmt_precision ? 1 : 0);
char buf[fmt_tot + 1];
@@ -1565,10 +1563,10 @@ static const struct print_operations json_pops = {
.print_group = print_group,
};
-static const struct print_operations stdout_pops = {
- .open_struct = stdout_open_struct,
- .close_struct = stdout_close_struct,
- .add_member = stdout_add_member,
+static const struct print_operations text_pops = {
+ .open_struct = text_open_struct,
+ .close_struct = text_close_struct,
+ .add_member = text_add_member,
.print_group = print_group,
};
@@ -1584,9 +1582,9 @@ static bool print_groups(struct cnt_group **groups)
static bool headers_printed = false;
bool print_data = true;
- if (output_mode == STDOUT &&
- (stdout_header_repeat || !headers_printed)) {
- unsigned int headers = stdout_lines % STDOUT_HEADER_REPEAT + 1;
+ if (output_mode == TEXT &&
+ (text_header_repeat || !headers_printed)) {
+ unsigned int headers = text_lines % TEXT_HEADER_REPEAT + 1;
if (headers == 1 || headers == 2)
for (struct cnt_group **grp = groups; *grp; grp++)
@@ -2492,7 +2490,7 @@ int main(int argc, char **argv)
list_device = true;
break;
case 'l':
- output_mode = STDOUT;
+ output_mode = TEXT;
break;
case 'h':
usage(argv[0]);
@@ -2505,7 +2503,7 @@ int main(int argc, char **argv)
}
if (output_mode == INTERACTIVE && (output_path || isatty(1) != 1))
- output_mode = STDOUT;
+ output_mode = TEXT;
if (output_path && strcmp(output_path, "-")) {
out = fopen(output_path, "w");
@@ -2519,7 +2517,7 @@ int main(int argc, char **argv)
out = stdout;
}
- stdout_header_repeat = output_mode == STDOUT && isatty(fileno(out));
+ text_header_repeat = output_mode == TEXT && isatty(fileno(out));
if (signal(SIGINT, sigint_handler) == SIG_ERR)
fprintf(stderr, "Failed to install signal handler!\n");
@@ -2531,8 +2529,8 @@ int main(int argc, char **argv)
pops = &term_pops;
interactive_stdin();
break;
- case STDOUT:
- pops = &stdout_pops;
+ case TEXT:
+ pops = &text_pops;
break;
case JSON:
pops = &json_pops;
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Intel-gfx] [PATCH i-g-t 3/3] intel_gpu_top: Add CVS output format
2023-02-03 11:16 [Intel-gfx] [PATCH i-g-t 0/3] More intel_gpu_top improvements Tvrtko Ursulin
2023-02-03 11:16 ` [Intel-gfx] [PATCH i-g-t 1/3] intel_gpu_top: Do not repeat header lines in non-interactive output Tvrtko Ursulin
2023-02-03 11:16 ` [Intel-gfx] [PATCH i-g-t 2/3] intel_gpu_top: Rename STDOUT to TEXT Tvrtko Ursulin
@ 2023-02-03 11:16 ` Tvrtko Ursulin
2023-02-03 11:22 ` [Intel-gfx] [igt-dev] " Ville Syrjälä
` (2 more replies)
2 siblings, 3 replies; 13+ messages in thread
From: Tvrtko Ursulin @ 2023-02-03 11:16 UTC (permalink / raw)
To: igt-dev, Intel-gfx; +Cc: Caleb Callaway
From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Add CVS output mode.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Caleb Callaway <caleb.callaway@intel.com>
---
man/intel_gpu_top.rst | 3 ++
tools/intel_gpu_top.c | 78 +++++++++++++++++++++++++++++++++++++++++--
2 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/man/intel_gpu_top.rst b/man/intel_gpu_top.rst
index 69834756b81e..77228277b9bf 100644
--- a/man/intel_gpu_top.rst
+++ b/man/intel_gpu_top.rst
@@ -31,6 +31,9 @@ OPTIONS
-h
Show help text.
+-c
+ Output CVS formatted data.
+
-J
Output JSON formatted data.
diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
index a980cc7043dc..4c425ca027e3 100644
--- a/tools/intel_gpu_top.c
+++ b/tools/intel_gpu_top.c
@@ -1268,6 +1268,7 @@ usage(const char *appname)
"\n"
"\tThe following parameters are optional:\n\n"
"\t[-h] Show this help text.\n"
+ "\t[-c] Output CVS formatted data.\n"
"\t[-J] Output JSON formatted data.\n"
"\t[-l] List plain text data.\n"
"\t[-o <file|->] Output to specified file or '-' for standard out.\n"
@@ -1283,6 +1284,7 @@ usage(const char *appname)
static enum {
INTERACTIVE,
TEXT,
+ CVS,
JSON
} output_mode;
@@ -1457,6 +1459,22 @@ text_add_member(const struct cnt_group *parent, struct cnt_item *item,
return len > 0 ? len : 0;
}
+static unsigned int
+cvs_add_member(const struct cnt_group *parent, struct cnt_item *item,
+ unsigned int headers)
+{
+ int len = 0;
+
+ if (headers)
+ fprintf(out, "%s %s", parent->display_name, item->unit);
+ else
+ len = fprintf(out, "%f",
+ pmu_calc(&item->pmu->val, item->d, item->t,
+ item->s));
+
+ return len > 0 ? len : 0;
+}
+
static void
term_open_struct(const char *name)
{
@@ -1540,6 +1558,46 @@ print_group(struct cnt_group *grp, unsigned int headers)
return consumed;
}
+static unsigned int cvs_count, prev_cvs_count;
+
+static void cvs_close_struct(void)
+{
+ assert(text_level > 0);
+ if (--text_level == 0) {
+ cvs_count = prev_cvs_count = 0;
+ text_lines++;
+ fputs("\n", out);
+ fflush(out);
+ }
+}
+
+static bool
+cvs_print_group(struct cnt_group *grp, unsigned int headers)
+{
+ unsigned int consumed = 0;
+ struct cnt_item *item;
+
+ if (!present_in_group(grp))
+ return false;
+
+ text_open_struct(grp->name);
+
+ for (item = grp->items; item->name; item++) {
+ if (!item->pmu || !item->pmu->present)
+ continue;
+
+ if (cvs_count != prev_cvs_count)
+ fprintf(out, ",");
+ prev_cvs_count = cvs_count++;
+
+ consumed += cvs_add_member(grp, item, headers);
+ }
+
+ cvs_close_struct();
+
+ return consumed;
+}
+
static bool
term_print_group(struct cnt_group *grp, unsigned int headers)
{
@@ -1570,6 +1628,13 @@ static const struct print_operations text_pops = {
.print_group = print_group,
};
+static const struct print_operations cvs_pops = {
+ .open_struct = text_open_struct,
+ .close_struct = cvs_close_struct,
+ .add_member = cvs_add_member,
+ .print_group = cvs_print_group,
+};
+
static const struct print_operations term_pops = {
.open_struct = term_open_struct,
.close_struct = term_close_struct,
@@ -1582,11 +1647,12 @@ static bool print_groups(struct cnt_group **groups)
static bool headers_printed = false;
bool print_data = true;
- if (output_mode == TEXT &&
+ if ((output_mode == TEXT || output_mode == CVS) &&
(text_header_repeat || !headers_printed)) {
+ const unsigned int header_lines = output_mode == TEXT ? 2 : 1;
unsigned int headers = text_lines % TEXT_HEADER_REPEAT + 1;
- if (headers == 1 || headers == 2)
+ if (headers > 0 && headers <= header_lines)
for (struct cnt_group **grp = groups; *grp; grp++)
print_data = pops->print_group(*grp, headers);
@@ -2469,7 +2535,7 @@ int main(int argc, char **argv)
char *codename = NULL;
/* Parse options */
- while ((ch = getopt(argc, argv, "o:s:d:pJLlh")) != -1) {
+ while ((ch = getopt(argc, argv, "o:s:d:pcJLlh")) != -1) {
switch (ch) {
case 'o':
output_path = optarg;
@@ -2483,6 +2549,9 @@ int main(int argc, char **argv)
case 'p':
physical_engines = true;
break;
+ case 'c':
+ output_mode = CVS;
+ break;
case 'J':
output_mode = JSON;
break;
@@ -2532,6 +2601,9 @@ int main(int argc, char **argv)
case TEXT:
pops = &text_pops;
break;
+ case CVS:
+ pops = &cvs_pops;
+ break;
case JSON:
pops = &json_pops;
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Intel-gfx] [igt-dev] [PATCH i-g-t 3/3] intel_gpu_top: Add CVS output format
2023-02-03 11:16 ` [Intel-gfx] [PATCH i-g-t 3/3] intel_gpu_top: Add CVS output format Tvrtko Ursulin
@ 2023-02-03 11:22 ` Ville Syrjälä
2023-02-03 11:27 ` Tvrtko Ursulin
2023-02-03 11:30 ` [Intel-gfx] [PATCH i-g-t 3/3] intel_gpu_top: Add CSV " Tvrtko Ursulin
2023-02-03 11:31 ` Tvrtko Ursulin
2 siblings, 1 reply; 13+ messages in thread
From: Ville Syrjälä @ 2023-02-03 11:22 UTC (permalink / raw)
To: Tvrtko Ursulin; +Cc: igt-dev, Intel-gfx, Caleb Callaway
On Fri, Feb 03, 2023 at 11:16:36AM +0000, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>
> Add CVS output mode.
Should that be csv?
>
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Cc: Caleb Callaway <caleb.callaway@intel.com>
> ---
> man/intel_gpu_top.rst | 3 ++
> tools/intel_gpu_top.c | 78 +++++++++++++++++++++++++++++++++++++++++--
> 2 files changed, 78 insertions(+), 3 deletions(-)
>
> diff --git a/man/intel_gpu_top.rst b/man/intel_gpu_top.rst
> index 69834756b81e..77228277b9bf 100644
> --- a/man/intel_gpu_top.rst
> +++ b/man/intel_gpu_top.rst
> @@ -31,6 +31,9 @@ OPTIONS
> -h
> Show help text.
>
> +-c
> + Output CVS formatted data.
> +
> -J
> Output JSON formatted data.
>
> diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
> index a980cc7043dc..4c425ca027e3 100644
> --- a/tools/intel_gpu_top.c
> +++ b/tools/intel_gpu_top.c
> @@ -1268,6 +1268,7 @@ usage(const char *appname)
> "\n"
> "\tThe following parameters are optional:\n\n"
> "\t[-h] Show this help text.\n"
> + "\t[-c] Output CVS formatted data.\n"
> "\t[-J] Output JSON formatted data.\n"
> "\t[-l] List plain text data.\n"
> "\t[-o <file|->] Output to specified file or '-' for standard out.\n"
> @@ -1283,6 +1284,7 @@ usage(const char *appname)
> static enum {
> INTERACTIVE,
> TEXT,
> + CVS,
> JSON
> } output_mode;
>
> @@ -1457,6 +1459,22 @@ text_add_member(const struct cnt_group *parent, struct cnt_item *item,
> return len > 0 ? len : 0;
> }
>
> +static unsigned int
> +cvs_add_member(const struct cnt_group *parent, struct cnt_item *item,
> + unsigned int headers)
> +{
> + int len = 0;
> +
> + if (headers)
> + fprintf(out, "%s %s", parent->display_name, item->unit);
> + else
> + len = fprintf(out, "%f",
> + pmu_calc(&item->pmu->val, item->d, item->t,
> + item->s));
> +
> + return len > 0 ? len : 0;
> +}
> +
> static void
> term_open_struct(const char *name)
> {
> @@ -1540,6 +1558,46 @@ print_group(struct cnt_group *grp, unsigned int headers)
> return consumed;
> }
>
> +static unsigned int cvs_count, prev_cvs_count;
> +
> +static void cvs_close_struct(void)
> +{
> + assert(text_level > 0);
> + if (--text_level == 0) {
> + cvs_count = prev_cvs_count = 0;
> + text_lines++;
> + fputs("\n", out);
> + fflush(out);
> + }
> +}
> +
> +static bool
> +cvs_print_group(struct cnt_group *grp, unsigned int headers)
> +{
> + unsigned int consumed = 0;
> + struct cnt_item *item;
> +
> + if (!present_in_group(grp))
> + return false;
> +
> + text_open_struct(grp->name);
> +
> + for (item = grp->items; item->name; item++) {
> + if (!item->pmu || !item->pmu->present)
> + continue;
> +
> + if (cvs_count != prev_cvs_count)
> + fprintf(out, ",");
> + prev_cvs_count = cvs_count++;
> +
> + consumed += cvs_add_member(grp, item, headers);
> + }
> +
> + cvs_close_struct();
> +
> + return consumed;
> +}
> +
> static bool
> term_print_group(struct cnt_group *grp, unsigned int headers)
> {
> @@ -1570,6 +1628,13 @@ static const struct print_operations text_pops = {
> .print_group = print_group,
> };
>
> +static const struct print_operations cvs_pops = {
> + .open_struct = text_open_struct,
> + .close_struct = cvs_close_struct,
> + .add_member = cvs_add_member,
> + .print_group = cvs_print_group,
> +};
> +
> static const struct print_operations term_pops = {
> .open_struct = term_open_struct,
> .close_struct = term_close_struct,
> @@ -1582,11 +1647,12 @@ static bool print_groups(struct cnt_group **groups)
> static bool headers_printed = false;
> bool print_data = true;
>
> - if (output_mode == TEXT &&
> + if ((output_mode == TEXT || output_mode == CVS) &&
> (text_header_repeat || !headers_printed)) {
> + const unsigned int header_lines = output_mode == TEXT ? 2 : 1;
> unsigned int headers = text_lines % TEXT_HEADER_REPEAT + 1;
>
> - if (headers == 1 || headers == 2)
> + if (headers > 0 && headers <= header_lines)
> for (struct cnt_group **grp = groups; *grp; grp++)
> print_data = pops->print_group(*grp, headers);
>
> @@ -2469,7 +2535,7 @@ int main(int argc, char **argv)
> char *codename = NULL;
>
> /* Parse options */
> - while ((ch = getopt(argc, argv, "o:s:d:pJLlh")) != -1) {
> + while ((ch = getopt(argc, argv, "o:s:d:pcJLlh")) != -1) {
> switch (ch) {
> case 'o':
> output_path = optarg;
> @@ -2483,6 +2549,9 @@ int main(int argc, char **argv)
> case 'p':
> physical_engines = true;
> break;
> + case 'c':
> + output_mode = CVS;
> + break;
> case 'J':
> output_mode = JSON;
> break;
> @@ -2532,6 +2601,9 @@ int main(int argc, char **argv)
> case TEXT:
> pops = &text_pops;
> break;
> + case CVS:
> + pops = &cvs_pops;
> + break;
> case JSON:
> pops = &json_pops;
> break;
> --
> 2.34.1
--
Ville Syrjälä
Intel
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Intel-gfx] [igt-dev] [PATCH i-g-t 3/3] intel_gpu_top: Add CVS output format
2023-02-03 11:22 ` [Intel-gfx] [igt-dev] " Ville Syrjälä
@ 2023-02-03 11:27 ` Tvrtko Ursulin
0 siblings, 0 replies; 13+ messages in thread
From: Tvrtko Ursulin @ 2023-02-03 11:27 UTC (permalink / raw)
To: Ville Syrjälä; +Cc: igt-dev, Intel-gfx, Caleb Callaway
On 03/02/2023 11:22, Ville Syrjälä wrote:
> On Fri, Feb 03, 2023 at 11:16:36AM +0000, Tvrtko Ursulin wrote:
>> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>>
>> Add CVS output mode.
>
> Should that be csv?
Lol at least I was consistent.. facepalm.
Regards,
Tvrtko
>>
>> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>> Cc: Caleb Callaway <caleb.callaway@intel.com>
>> ---
>> man/intel_gpu_top.rst | 3 ++
>> tools/intel_gpu_top.c | 78 +++++++++++++++++++++++++++++++++++++++++--
>> 2 files changed, 78 insertions(+), 3 deletions(-)
>>
>> diff --git a/man/intel_gpu_top.rst b/man/intel_gpu_top.rst
>> index 69834756b81e..77228277b9bf 100644
>> --- a/man/intel_gpu_top.rst
>> +++ b/man/intel_gpu_top.rst
>> @@ -31,6 +31,9 @@ OPTIONS
>> -h
>> Show help text.
>>
>> +-c
>> + Output CVS formatted data.
>> +
>> -J
>> Output JSON formatted data.
>>
>> diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
>> index a980cc7043dc..4c425ca027e3 100644
>> --- a/tools/intel_gpu_top.c
>> +++ b/tools/intel_gpu_top.c
>> @@ -1268,6 +1268,7 @@ usage(const char *appname)
>> "\n"
>> "\tThe following parameters are optional:\n\n"
>> "\t[-h] Show this help text.\n"
>> + "\t[-c] Output CVS formatted data.\n"
>> "\t[-J] Output JSON formatted data.\n"
>> "\t[-l] List plain text data.\n"
>> "\t[-o <file|->] Output to specified file or '-' for standard out.\n"
>> @@ -1283,6 +1284,7 @@ usage(const char *appname)
>> static enum {
>> INTERACTIVE,
>> TEXT,
>> + CVS,
>> JSON
>> } output_mode;
>>
>> @@ -1457,6 +1459,22 @@ text_add_member(const struct cnt_group *parent, struct cnt_item *item,
>> return len > 0 ? len : 0;
>> }
>>
>> +static unsigned int
>> +cvs_add_member(const struct cnt_group *parent, struct cnt_item *item,
>> + unsigned int headers)
>> +{
>> + int len = 0;
>> +
>> + if (headers)
>> + fprintf(out, "%s %s", parent->display_name, item->unit);
>> + else
>> + len = fprintf(out, "%f",
>> + pmu_calc(&item->pmu->val, item->d, item->t,
>> + item->s));
>> +
>> + return len > 0 ? len : 0;
>> +}
>> +
>> static void
>> term_open_struct(const char *name)
>> {
>> @@ -1540,6 +1558,46 @@ print_group(struct cnt_group *grp, unsigned int headers)
>> return consumed;
>> }
>>
>> +static unsigned int cvs_count, prev_cvs_count;
>> +
>> +static void cvs_close_struct(void)
>> +{
>> + assert(text_level > 0);
>> + if (--text_level == 0) {
>> + cvs_count = prev_cvs_count = 0;
>> + text_lines++;
>> + fputs("\n", out);
>> + fflush(out);
>> + }
>> +}
>> +
>> +static bool
>> +cvs_print_group(struct cnt_group *grp, unsigned int headers)
>> +{
>> + unsigned int consumed = 0;
>> + struct cnt_item *item;
>> +
>> + if (!present_in_group(grp))
>> + return false;
>> +
>> + text_open_struct(grp->name);
>> +
>> + for (item = grp->items; item->name; item++) {
>> + if (!item->pmu || !item->pmu->present)
>> + continue;
>> +
>> + if (cvs_count != prev_cvs_count)
>> + fprintf(out, ",");
>> + prev_cvs_count = cvs_count++;
>> +
>> + consumed += cvs_add_member(grp, item, headers);
>> + }
>> +
>> + cvs_close_struct();
>> +
>> + return consumed;
>> +}
>> +
>> static bool
>> term_print_group(struct cnt_group *grp, unsigned int headers)
>> {
>> @@ -1570,6 +1628,13 @@ static const struct print_operations text_pops = {
>> .print_group = print_group,
>> };
>>
>> +static const struct print_operations cvs_pops = {
>> + .open_struct = text_open_struct,
>> + .close_struct = cvs_close_struct,
>> + .add_member = cvs_add_member,
>> + .print_group = cvs_print_group,
>> +};
>> +
>> static const struct print_operations term_pops = {
>> .open_struct = term_open_struct,
>> .close_struct = term_close_struct,
>> @@ -1582,11 +1647,12 @@ static bool print_groups(struct cnt_group **groups)
>> static bool headers_printed = false;
>> bool print_data = true;
>>
>> - if (output_mode == TEXT &&
>> + if ((output_mode == TEXT || output_mode == CVS) &&
>> (text_header_repeat || !headers_printed)) {
>> + const unsigned int header_lines = output_mode == TEXT ? 2 : 1;
>> unsigned int headers = text_lines % TEXT_HEADER_REPEAT + 1;
>>
>> - if (headers == 1 || headers == 2)
>> + if (headers > 0 && headers <= header_lines)
>> for (struct cnt_group **grp = groups; *grp; grp++)
>> print_data = pops->print_group(*grp, headers);
>>
>> @@ -2469,7 +2535,7 @@ int main(int argc, char **argv)
>> char *codename = NULL;
>>
>> /* Parse options */
>> - while ((ch = getopt(argc, argv, "o:s:d:pJLlh")) != -1) {
>> + while ((ch = getopt(argc, argv, "o:s:d:pcJLlh")) != -1) {
>> switch (ch) {
>> case 'o':
>> output_path = optarg;
>> @@ -2483,6 +2549,9 @@ int main(int argc, char **argv)
>> case 'p':
>> physical_engines = true;
>> break;
>> + case 'c':
>> + output_mode = CVS;
>> + break;
>> case 'J':
>> output_mode = JSON;
>> break;
>> @@ -2532,6 +2601,9 @@ int main(int argc, char **argv)
>> case TEXT:
>> pops = &text_pops;
>> break;
>> + case CVS:
>> + pops = &cvs_pops;
>> + break;
>> case JSON:
>> pops = &json_pops;
>> break;
>> --
>> 2.34.1
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Intel-gfx] [PATCH i-g-t 3/3] intel_gpu_top: Add CSV output format
2023-02-03 11:16 ` [Intel-gfx] [PATCH i-g-t 3/3] intel_gpu_top: Add CVS output format Tvrtko Ursulin
2023-02-03 11:22 ` [Intel-gfx] [igt-dev] " Ville Syrjälä
@ 2023-02-03 11:30 ` Tvrtko Ursulin
2023-02-03 11:31 ` Tvrtko Ursulin
2 siblings, 0 replies; 13+ messages in thread
From: Tvrtko Ursulin @ 2023-02-03 11:30 UTC (permalink / raw)
To: igt-dev, Intel-gfx; +Cc: Caleb Callaway
From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Add CSV output mode.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Caleb Callaway <caleb.callaway@intel.com>
---
man/intel_gpu_top.rst | 3 ++
tools/intel_gpu_top.c | 78 +++++++++++++++++++++++++++++++++++++++++--
2 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/man/intel_gpu_top.rst b/man/intel_gpu_top.rst
index 69834756b81e..77228277b9bf 100644
--- a/man/intel_gpu_top.rst
+++ b/man/intel_gpu_top.rst
@@ -31,6 +31,9 @@ OPTIONS
-h
Show help text.
+-c
+ Output CVS formatted data.
+
-J
Output JSON formatted data.
diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
index a980cc7043dc..2e1365959d8b 100644
--- a/tools/intel_gpu_top.c
+++ b/tools/intel_gpu_top.c
@@ -1268,6 +1268,7 @@ usage(const char *appname)
"\n"
"\tThe following parameters are optional:\n\n"
"\t[-h] Show this help text.\n"
+ "\t[-c] Output CSV formatted data.\n"
"\t[-J] Output JSON formatted data.\n"
"\t[-l] List plain text data.\n"
"\t[-o <file|->] Output to specified file or '-' for standard out.\n"
@@ -1283,6 +1284,7 @@ usage(const char *appname)
static enum {
INTERACTIVE,
TEXT,
+ CSV,
JSON
} output_mode;
@@ -1457,6 +1459,22 @@ text_add_member(const struct cnt_group *parent, struct cnt_item *item,
return len > 0 ? len : 0;
}
+static unsigned int
+csv_add_member(const struct cnt_group *parent, struct cnt_item *item,
+ unsigned int headers)
+{
+ int len = 0;
+
+ if (headers)
+ fprintf(out, "%s %s", parent->display_name, item->unit);
+ else
+ len = fprintf(out, "%f",
+ pmu_calc(&item->pmu->val, item->d, item->t,
+ item->s));
+
+ return len > 0 ? len : 0;
+}
+
static void
term_open_struct(const char *name)
{
@@ -1540,6 +1558,46 @@ print_group(struct cnt_group *grp, unsigned int headers)
return consumed;
}
+static unsigned int csv_count, prev_csv_count;
+
+static void csv_close_struct(void)
+{
+ assert(text_level > 0);
+ if (--text_level == 0) {
+ csv_count = prev_csv_count = 0;
+ text_lines++;
+ fputs("\n", out);
+ fflush(out);
+ }
+}
+
+static bool
+csv_print_group(struct cnt_group *grp, unsigned int headers)
+{
+ unsigned int consumed = 0;
+ struct cnt_item *item;
+
+ if (!present_in_group(grp))
+ return false;
+
+ text_open_struct(grp->name);
+
+ for (item = grp->items; item->name; item++) {
+ if (!item->pmu || !item->pmu->present)
+ continue;
+
+ if (csv_count != prev_csv_count)
+ fprintf(out, ",");
+ prev_csv_count = csv_count++;
+
+ consumed += csv_add_member(grp, item, headers);
+ }
+
+ csv_close_struct();
+
+ return consumed;
+}
+
static bool
term_print_group(struct cnt_group *grp, unsigned int headers)
{
@@ -1570,6 +1628,13 @@ static const struct print_operations text_pops = {
.print_group = print_group,
};
+static const struct print_operations csv_pops = {
+ .open_struct = text_open_struct,
+ .close_struct = csv_close_struct,
+ .add_member = csv_add_member,
+ .print_group = csv_print_group,
+};
+
static const struct print_operations term_pops = {
.open_struct = term_open_struct,
.close_struct = term_close_struct,
@@ -1582,11 +1647,12 @@ static bool print_groups(struct cnt_group **groups)
static bool headers_printed = false;
bool print_data = true;
- if (output_mode == TEXT &&
+ if ((output_mode == TEXT || output_mode == CSV) &&
(text_header_repeat || !headers_printed)) {
+ const unsigned int header_lines = output_mode == TEXT ? 2 : 1;
unsigned int headers = text_lines % TEXT_HEADER_REPEAT + 1;
- if (headers == 1 || headers == 2)
+ if (headers > 0 && headers <= header_lines)
for (struct cnt_group **grp = groups; *grp; grp++)
print_data = pops->print_group(*grp, headers);
@@ -2469,7 +2535,7 @@ int main(int argc, char **argv)
char *codename = NULL;
/* Parse options */
- while ((ch = getopt(argc, argv, "o:s:d:pJLlh")) != -1) {
+ while ((ch = getopt(argc, argv, "o:s:d:pcJLlh")) != -1) {
switch (ch) {
case 'o':
output_path = optarg;
@@ -2483,6 +2549,9 @@ int main(int argc, char **argv)
case 'p':
physical_engines = true;
break;
+ case 'c':
+ output_mode = CSV;
+ break;
case 'J':
output_mode = JSON;
break;
@@ -2532,6 +2601,9 @@ int main(int argc, char **argv)
case TEXT:
pops = &text_pops;
break;
+ case CSV:
+ pops = &csv_pops;
+ break;
case JSON:
pops = &json_pops;
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Intel-gfx] [PATCH i-g-t 3/3] intel_gpu_top: Add CSV output format
2023-02-03 11:16 ` [Intel-gfx] [PATCH i-g-t 3/3] intel_gpu_top: Add CVS output format Tvrtko Ursulin
2023-02-03 11:22 ` [Intel-gfx] [igt-dev] " Ville Syrjälä
2023-02-03 11:30 ` [Intel-gfx] [PATCH i-g-t 3/3] intel_gpu_top: Add CSV " Tvrtko Ursulin
@ 2023-02-03 11:31 ` Tvrtko Ursulin
2023-02-07 13:29 ` Kamil Konieczny
2 siblings, 1 reply; 13+ messages in thread
From: Tvrtko Ursulin @ 2023-02-03 11:31 UTC (permalink / raw)
To: igt-dev, Intel-gfx; +Cc: Caleb Callaway
From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Add CSV output mode.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Caleb Callaway <caleb.callaway@intel.com>
---
man/intel_gpu_top.rst | 3 ++
tools/intel_gpu_top.c | 78 +++++++++++++++++++++++++++++++++++++++++--
2 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/man/intel_gpu_top.rst b/man/intel_gpu_top.rst
index 69834756b81e..2d041457a95e 100644
--- a/man/intel_gpu_top.rst
+++ b/man/intel_gpu_top.rst
@@ -31,6 +31,9 @@ OPTIONS
-h
Show help text.
+-c
+ Output CSV formatted data.
+
-J
Output JSON formatted data.
diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
index a980cc7043dc..2e1365959d8b 100644
--- a/tools/intel_gpu_top.c
+++ b/tools/intel_gpu_top.c
@@ -1268,6 +1268,7 @@ usage(const char *appname)
"\n"
"\tThe following parameters are optional:\n\n"
"\t[-h] Show this help text.\n"
+ "\t[-c] Output CSV formatted data.\n"
"\t[-J] Output JSON formatted data.\n"
"\t[-l] List plain text data.\n"
"\t[-o <file|->] Output to specified file or '-' for standard out.\n"
@@ -1283,6 +1284,7 @@ usage(const char *appname)
static enum {
INTERACTIVE,
TEXT,
+ CSV,
JSON
} output_mode;
@@ -1457,6 +1459,22 @@ text_add_member(const struct cnt_group *parent, struct cnt_item *item,
return len > 0 ? len : 0;
}
+static unsigned int
+csv_add_member(const struct cnt_group *parent, struct cnt_item *item,
+ unsigned int headers)
+{
+ int len = 0;
+
+ if (headers)
+ fprintf(out, "%s %s", parent->display_name, item->unit);
+ else
+ len = fprintf(out, "%f",
+ pmu_calc(&item->pmu->val, item->d, item->t,
+ item->s));
+
+ return len > 0 ? len : 0;
+}
+
static void
term_open_struct(const char *name)
{
@@ -1540,6 +1558,46 @@ print_group(struct cnt_group *grp, unsigned int headers)
return consumed;
}
+static unsigned int csv_count, prev_csv_count;
+
+static void csv_close_struct(void)
+{
+ assert(text_level > 0);
+ if (--text_level == 0) {
+ csv_count = prev_csv_count = 0;
+ text_lines++;
+ fputs("\n", out);
+ fflush(out);
+ }
+}
+
+static bool
+csv_print_group(struct cnt_group *grp, unsigned int headers)
+{
+ unsigned int consumed = 0;
+ struct cnt_item *item;
+
+ if (!present_in_group(grp))
+ return false;
+
+ text_open_struct(grp->name);
+
+ for (item = grp->items; item->name; item++) {
+ if (!item->pmu || !item->pmu->present)
+ continue;
+
+ if (csv_count != prev_csv_count)
+ fprintf(out, ",");
+ prev_csv_count = csv_count++;
+
+ consumed += csv_add_member(grp, item, headers);
+ }
+
+ csv_close_struct();
+
+ return consumed;
+}
+
static bool
term_print_group(struct cnt_group *grp, unsigned int headers)
{
@@ -1570,6 +1628,13 @@ static const struct print_operations text_pops = {
.print_group = print_group,
};
+static const struct print_operations csv_pops = {
+ .open_struct = text_open_struct,
+ .close_struct = csv_close_struct,
+ .add_member = csv_add_member,
+ .print_group = csv_print_group,
+};
+
static const struct print_operations term_pops = {
.open_struct = term_open_struct,
.close_struct = term_close_struct,
@@ -1582,11 +1647,12 @@ static bool print_groups(struct cnt_group **groups)
static bool headers_printed = false;
bool print_data = true;
- if (output_mode == TEXT &&
+ if ((output_mode == TEXT || output_mode == CSV) &&
(text_header_repeat || !headers_printed)) {
+ const unsigned int header_lines = output_mode == TEXT ? 2 : 1;
unsigned int headers = text_lines % TEXT_HEADER_REPEAT + 1;
- if (headers == 1 || headers == 2)
+ if (headers > 0 && headers <= header_lines)
for (struct cnt_group **grp = groups; *grp; grp++)
print_data = pops->print_group(*grp, headers);
@@ -2469,7 +2535,7 @@ int main(int argc, char **argv)
char *codename = NULL;
/* Parse options */
- while ((ch = getopt(argc, argv, "o:s:d:pJLlh")) != -1) {
+ while ((ch = getopt(argc, argv, "o:s:d:pcJLlh")) != -1) {
switch (ch) {
case 'o':
output_path = optarg;
@@ -2483,6 +2549,9 @@ int main(int argc, char **argv)
case 'p':
physical_engines = true;
break;
+ case 'c':
+ output_mode = CSV;
+ break;
case 'J':
output_mode = JSON;
break;
@@ -2532,6 +2601,9 @@ int main(int argc, char **argv)
case TEXT:
pops = &text_pops;
break;
+ case CSV:
+ pops = &csv_pops;
+ break;
case JSON:
pops = &json_pops;
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Intel-gfx] [igt-dev] [PATCH i-g-t 2/3] intel_gpu_top: Rename STDOUT to TEXT
2023-02-03 11:16 ` [Intel-gfx] [PATCH i-g-t 2/3] intel_gpu_top: Rename STDOUT to TEXT Tvrtko Ursulin
@ 2023-02-07 13:15 ` Kamil Konieczny
0 siblings, 0 replies; 13+ messages in thread
From: Kamil Konieczny @ 2023-02-07 13:15 UTC (permalink / raw)
To: igt-dev; +Cc: Intel-gfx, Caleb Callaway
On 2023-02-03 at 11:16:35 +0000, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>
> Internal cleanup only - the name text is more accurate given the output
> can also go to a file.
>
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Cc: Caleb Callaway <caleb.callaway@intel.com>
Lgtm,
Reviewed-by: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> ---
> tools/intel_gpu_top.c | 54 +++++++++++++++++++++----------------------
> 1 file changed, 26 insertions(+), 28 deletions(-)
>
> diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
> index e2a7f4753099..a980cc7043dc 100644
> --- a/tools/intel_gpu_top.c
> +++ b/tools/intel_gpu_top.c
> @@ -1282,7 +1282,7 @@ usage(const char *appname)
>
> static enum {
> INTERACTIVE,
> - STDOUT,
> + TEXT,
> JSON
> } output_mode;
>
> @@ -1387,33 +1387,31 @@ json_add_member(const struct cnt_group *parent, struct cnt_item *item,
> return 1;
> }
>
> -static unsigned int stdout_level;
> +static unsigned int text_level;
>
> -#define STDOUT_HEADER_REPEAT 20
> -static unsigned int stdout_lines = STDOUT_HEADER_REPEAT;
> -static bool stdout_header_repeat;
> +#define TEXT_HEADER_REPEAT 20
> +static unsigned int text_lines = TEXT_HEADER_REPEAT;
> +static bool text_header_repeat;
>
> -static void
> -stdout_open_struct(const char *name)
> +static void text_open_struct(const char *name)
> {
> - stdout_level++;
> - assert(stdout_level > 0);
> + text_level++;
> + assert(text_level > 0);
> }
>
> -static void
> -stdout_close_struct(void)
> +static void text_close_struct(void)
> {
> - assert(stdout_level > 0);
> - if (--stdout_level == 0) {
> - stdout_lines++;
> + assert(text_level > 0);
> + if (--text_level == 0) {
> + text_lines++;
> fputs("\n", out);
> fflush(out);
> }
> }
>
> static unsigned int
> -stdout_add_member(const struct cnt_group *parent, struct cnt_item *item,
> - unsigned int headers)
> +text_add_member(const struct cnt_group *parent, struct cnt_item *item,
> + unsigned int headers)
> {
> unsigned int fmt_tot = item->fmt_width + (item->fmt_precision ? 1 : 0);
> char buf[fmt_tot + 1];
> @@ -1565,10 +1563,10 @@ static const struct print_operations json_pops = {
> .print_group = print_group,
> };
>
> -static const struct print_operations stdout_pops = {
> - .open_struct = stdout_open_struct,
> - .close_struct = stdout_close_struct,
> - .add_member = stdout_add_member,
> +static const struct print_operations text_pops = {
> + .open_struct = text_open_struct,
> + .close_struct = text_close_struct,
> + .add_member = text_add_member,
> .print_group = print_group,
> };
>
> @@ -1584,9 +1582,9 @@ static bool print_groups(struct cnt_group **groups)
> static bool headers_printed = false;
> bool print_data = true;
>
> - if (output_mode == STDOUT &&
> - (stdout_header_repeat || !headers_printed)) {
> - unsigned int headers = stdout_lines % STDOUT_HEADER_REPEAT + 1;
> + if (output_mode == TEXT &&
> + (text_header_repeat || !headers_printed)) {
> + unsigned int headers = text_lines % TEXT_HEADER_REPEAT + 1;
>
> if (headers == 1 || headers == 2)
> for (struct cnt_group **grp = groups; *grp; grp++)
> @@ -2492,7 +2490,7 @@ int main(int argc, char **argv)
> list_device = true;
> break;
> case 'l':
> - output_mode = STDOUT;
> + output_mode = TEXT;
> break;
> case 'h':
> usage(argv[0]);
> @@ -2505,7 +2503,7 @@ int main(int argc, char **argv)
> }
>
> if (output_mode == INTERACTIVE && (output_path || isatty(1) != 1))
> - output_mode = STDOUT;
> + output_mode = TEXT;
>
> if (output_path && strcmp(output_path, "-")) {
> out = fopen(output_path, "w");
> @@ -2519,7 +2517,7 @@ int main(int argc, char **argv)
> out = stdout;
> }
>
> - stdout_header_repeat = output_mode == STDOUT && isatty(fileno(out));
> + text_header_repeat = output_mode == TEXT && isatty(fileno(out));
>
> if (signal(SIGINT, sigint_handler) == SIG_ERR)
> fprintf(stderr, "Failed to install signal handler!\n");
> @@ -2531,8 +2529,8 @@ int main(int argc, char **argv)
> pops = &term_pops;
> interactive_stdin();
> break;
> - case STDOUT:
> - pops = &stdout_pops;
> + case TEXT:
> + pops = &text_pops;
> break;
> case JSON:
> pops = &json_pops;
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Intel-gfx] [PATCH i-g-t 1/3] intel_gpu_top: Do not repeat header lines in non-interactive output
2023-02-03 11:16 ` [Intel-gfx] [PATCH i-g-t 1/3] intel_gpu_top: Do not repeat header lines in non-interactive output Tvrtko Ursulin
@ 2023-02-07 13:25 ` Kamil Konieczny
2023-02-08 12:31 ` Kamil Konieczny
1 sibling, 0 replies; 13+ messages in thread
From: Kamil Konieczny @ 2023-02-07 13:25 UTC (permalink / raw)
To: igt-dev; +Cc: Intel-gfx, Caleb Callaway
On 2023-02-03 at 11:16:34 +0000, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>
> If output is redirected to a file, or a pipe, lets not repeat the headers
> because that can usually mean user is trying to parse the data later and
> so repeated headers are a hindrance.
>
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Cc: Caleb Callaway <caleb.callaway@intel.com>
Reviewed-by: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> ---
> tools/intel_gpu_top.c | 19 ++++++++++++++-----
> 1 file changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
> index 0a1de41b3374..e2a7f4753099 100644
> --- a/tools/intel_gpu_top.c
> +++ b/tools/intel_gpu_top.c
> @@ -1391,6 +1391,7 @@ static unsigned int stdout_level;
>
> #define STDOUT_HEADER_REPEAT 20
> static unsigned int stdout_lines = STDOUT_HEADER_REPEAT;
> +static bool stdout_header_repeat;
>
> static void
> stdout_open_struct(const char *name)
> @@ -1580,16 +1581,22 @@ static const struct print_operations term_pops = {
>
> static bool print_groups(struct cnt_group **groups)
> {
> - unsigned int headers = stdout_lines % STDOUT_HEADER_REPEAT + 1;
> + static bool headers_printed = false;
> bool print_data = true;
>
> - if (output_mode == STDOUT && (headers == 1 || headers == 2)) {
> - for (struct cnt_group **grp = groups; *grp; grp++)
> - print_data = pops->print_group(*grp, headers);
> + if (output_mode == STDOUT &&
> + (stdout_header_repeat || !headers_printed)) {
> + unsigned int headers = stdout_lines % STDOUT_HEADER_REPEAT + 1;
> +
> + if (headers == 1 || headers == 2)
> + for (struct cnt_group **grp = groups; *grp; grp++)
> + print_data = pops->print_group(*grp, headers);
> +
> + headers_printed = print_data;
> }
>
> for (struct cnt_group **grp = groups; print_data && *grp; grp++)
> - pops->print_group(*grp, false);
> + pops->print_group(*grp, 0);
>
> return print_data;
> }
> @@ -2512,6 +2519,8 @@ int main(int argc, char **argv)
> out = stdout;
> }
>
> + stdout_header_repeat = output_mode == STDOUT && isatty(fileno(out));
> +
> if (signal(SIGINT, sigint_handler) == SIG_ERR)
> fprintf(stderr, "Failed to install signal handler!\n");
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Intel-gfx] [PATCH i-g-t 3/3] intel_gpu_top: Add CSV output format
2023-02-03 11:31 ` Tvrtko Ursulin
@ 2023-02-07 13:29 ` Kamil Konieczny
0 siblings, 0 replies; 13+ messages in thread
From: Kamil Konieczny @ 2023-02-07 13:29 UTC (permalink / raw)
To: igt-dev; +Cc: Intel-gfx, Caleb Callaway
On 2023-02-03 at 11:31:19 +0000, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>
> Add CSV output mode.
>
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Cc: Caleb Callaway <caleb.callaway@intel.com>
Reviewed-by: Kamil Konieczny <kamil.konieczny@linux.intel.com>
> ---
> man/intel_gpu_top.rst | 3 ++
> tools/intel_gpu_top.c | 78 +++++++++++++++++++++++++++++++++++++++++--
> 2 files changed, 78 insertions(+), 3 deletions(-)
>
> diff --git a/man/intel_gpu_top.rst b/man/intel_gpu_top.rst
> index 69834756b81e..2d041457a95e 100644
> --- a/man/intel_gpu_top.rst
> +++ b/man/intel_gpu_top.rst
> @@ -31,6 +31,9 @@ OPTIONS
> -h
> Show help text.
>
> +-c
> + Output CSV formatted data.
> +
> -J
> Output JSON formatted data.
>
> diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
> index a980cc7043dc..2e1365959d8b 100644
> --- a/tools/intel_gpu_top.c
> +++ b/tools/intel_gpu_top.c
> @@ -1268,6 +1268,7 @@ usage(const char *appname)
> "\n"
> "\tThe following parameters are optional:\n\n"
> "\t[-h] Show this help text.\n"
> + "\t[-c] Output CSV formatted data.\n"
> "\t[-J] Output JSON formatted data.\n"
> "\t[-l] List plain text data.\n"
> "\t[-o <file|->] Output to specified file or '-' for standard out.\n"
> @@ -1283,6 +1284,7 @@ usage(const char *appname)
> static enum {
> INTERACTIVE,
> TEXT,
> + CSV,
> JSON
> } output_mode;
>
> @@ -1457,6 +1459,22 @@ text_add_member(const struct cnt_group *parent, struct cnt_item *item,
> return len > 0 ? len : 0;
> }
>
> +static unsigned int
> +csv_add_member(const struct cnt_group *parent, struct cnt_item *item,
> + unsigned int headers)
> +{
> + int len = 0;
> +
> + if (headers)
> + fprintf(out, "%s %s", parent->display_name, item->unit);
> + else
> + len = fprintf(out, "%f",
> + pmu_calc(&item->pmu->val, item->d, item->t,
> + item->s));
> +
> + return len > 0 ? len : 0;
> +}
> +
> static void
> term_open_struct(const char *name)
> {
> @@ -1540,6 +1558,46 @@ print_group(struct cnt_group *grp, unsigned int headers)
> return consumed;
> }
>
> +static unsigned int csv_count, prev_csv_count;
> +
> +static void csv_close_struct(void)
> +{
> + assert(text_level > 0);
> + if (--text_level == 0) {
> + csv_count = prev_csv_count = 0;
> + text_lines++;
> + fputs("\n", out);
> + fflush(out);
> + }
> +}
> +
> +static bool
> +csv_print_group(struct cnt_group *grp, unsigned int headers)
> +{
> + unsigned int consumed = 0;
> + struct cnt_item *item;
> +
> + if (!present_in_group(grp))
> + return false;
> +
> + text_open_struct(grp->name);
> +
> + for (item = grp->items; item->name; item++) {
> + if (!item->pmu || !item->pmu->present)
> + continue;
> +
> + if (csv_count != prev_csv_count)
> + fprintf(out, ",");
> + prev_csv_count = csv_count++;
> +
> + consumed += csv_add_member(grp, item, headers);
> + }
> +
> + csv_close_struct();
> +
> + return consumed;
> +}
> +
> static bool
> term_print_group(struct cnt_group *grp, unsigned int headers)
> {
> @@ -1570,6 +1628,13 @@ static const struct print_operations text_pops = {
> .print_group = print_group,
> };
>
> +static const struct print_operations csv_pops = {
> + .open_struct = text_open_struct,
> + .close_struct = csv_close_struct,
> + .add_member = csv_add_member,
> + .print_group = csv_print_group,
> +};
> +
> static const struct print_operations term_pops = {
> .open_struct = term_open_struct,
> .close_struct = term_close_struct,
> @@ -1582,11 +1647,12 @@ static bool print_groups(struct cnt_group **groups)
> static bool headers_printed = false;
> bool print_data = true;
>
> - if (output_mode == TEXT &&
> + if ((output_mode == TEXT || output_mode == CSV) &&
> (text_header_repeat || !headers_printed)) {
> + const unsigned int header_lines = output_mode == TEXT ? 2 : 1;
> unsigned int headers = text_lines % TEXT_HEADER_REPEAT + 1;
>
> - if (headers == 1 || headers == 2)
> + if (headers > 0 && headers <= header_lines)
> for (struct cnt_group **grp = groups; *grp; grp++)
> print_data = pops->print_group(*grp, headers);
>
> @@ -2469,7 +2535,7 @@ int main(int argc, char **argv)
> char *codename = NULL;
>
> /* Parse options */
> - while ((ch = getopt(argc, argv, "o:s:d:pJLlh")) != -1) {
> + while ((ch = getopt(argc, argv, "o:s:d:pcJLlh")) != -1) {
> switch (ch) {
> case 'o':
> output_path = optarg;
> @@ -2483,6 +2549,9 @@ int main(int argc, char **argv)
> case 'p':
> physical_engines = true;
> break;
> + case 'c':
> + output_mode = CSV;
> + break;
> case 'J':
> output_mode = JSON;
> break;
> @@ -2532,6 +2601,9 @@ int main(int argc, char **argv)
> case TEXT:
> pops = &text_pops;
> break;
> + case CSV:
> + pops = &csv_pops;
> + break;
> case JSON:
> pops = &json_pops;
> break;
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Intel-gfx] [PATCH i-g-t 1/3] intel_gpu_top: Do not repeat header lines in non-interactive output
2023-02-03 11:16 ` [Intel-gfx] [PATCH i-g-t 1/3] intel_gpu_top: Do not repeat header lines in non-interactive output Tvrtko Ursulin
2023-02-07 13:25 ` Kamil Konieczny
@ 2023-02-08 12:31 ` Kamil Konieczny
2023-02-09 8:24 ` Tvrtko Ursulin
1 sibling, 1 reply; 13+ messages in thread
From: Kamil Konieczny @ 2023-02-08 12:31 UTC (permalink / raw)
To: igt-dev; +Cc: Intel-gfx, Caleb Callaway
Hi Tvrtko,
one small nit, see below.
On 2023-02-03 at 11:16:34 +0000, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>
> If output is redirected to a file, or a pipe, lets not repeat the headers
> because that can usually mean user is trying to parse the data later and
> so repeated headers are a hindrance.
>
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Cc: Caleb Callaway <caleb.callaway@intel.com>
> ---
> tools/intel_gpu_top.c | 19 ++++++++++++++-----
> 1 file changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
> index 0a1de41b3374..e2a7f4753099 100644
> --- a/tools/intel_gpu_top.c
> +++ b/tools/intel_gpu_top.c
> @@ -1391,6 +1391,7 @@ static unsigned int stdout_level;
>
> #define STDOUT_HEADER_REPEAT 20
> static unsigned int stdout_lines = STDOUT_HEADER_REPEAT;
> +static bool stdout_header_repeat;
>
> static void
> stdout_open_struct(const char *name)
> @@ -1580,16 +1581,22 @@ static const struct print_operations term_pops = {
>
> static bool print_groups(struct cnt_group **groups)
> {
> - unsigned int headers = stdout_lines % STDOUT_HEADER_REPEAT + 1;
> + static bool headers_printed = false;
----------------------------------- ^
Remove this initialization (use checkpatch from Linux kernel).
Please correct and resend (you can keep my r-b).
Regards,
Kamil
> bool print_data = true;
>
> - if (output_mode == STDOUT && (headers == 1 || headers == 2)) {
> - for (struct cnt_group **grp = groups; *grp; grp++)
> - print_data = pops->print_group(*grp, headers);
> + if (output_mode == STDOUT &&
> + (stdout_header_repeat || !headers_printed)) {
> + unsigned int headers = stdout_lines % STDOUT_HEADER_REPEAT + 1;
> +
> + if (headers == 1 || headers == 2)
> + for (struct cnt_group **grp = groups; *grp; grp++)
> + print_data = pops->print_group(*grp, headers);
> +
> + headers_printed = print_data;
> }
>
> for (struct cnt_group **grp = groups; print_data && *grp; grp++)
> - pops->print_group(*grp, false);
> + pops->print_group(*grp, 0);
>
> return print_data;
> }
> @@ -2512,6 +2519,8 @@ int main(int argc, char **argv)
> out = stdout;
> }
>
> + stdout_header_repeat = output_mode == STDOUT && isatty(fileno(out));
> +
> if (signal(SIGINT, sigint_handler) == SIG_ERR)
> fprintf(stderr, "Failed to install signal handler!\n");
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Intel-gfx] [PATCH i-g-t 1/3] intel_gpu_top: Do not repeat header lines in non-interactive output
2023-02-08 12:31 ` Kamil Konieczny
@ 2023-02-09 8:24 ` Tvrtko Ursulin
0 siblings, 0 replies; 13+ messages in thread
From: Tvrtko Ursulin @ 2023-02-09 8:24 UTC (permalink / raw)
To: Kamil Konieczny, igt-dev, Intel-gfx, Caleb Callaway
On 08/02/2023 12:31, Kamil Konieczny wrote:
> Hi Tvrtko,
>
> one small nit, see below.
>
> On 2023-02-03 at 11:16:34 +0000, Tvrtko Ursulin wrote:
>> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>>
>> If output is redirected to a file, or a pipe, lets not repeat the headers
>> because that can usually mean user is trying to parse the data later and
>> so repeated headers are a hindrance.
>>
>> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>> Cc: Caleb Callaway <caleb.callaway@intel.com>
>> ---
>> tools/intel_gpu_top.c | 19 ++++++++++++++-----
>> 1 file changed, 14 insertions(+), 5 deletions(-)
>>
>> diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
>> index 0a1de41b3374..e2a7f4753099 100644
>> --- a/tools/intel_gpu_top.c
>> +++ b/tools/intel_gpu_top.c
>> @@ -1391,6 +1391,7 @@ static unsigned int stdout_level;
>>
>> #define STDOUT_HEADER_REPEAT 20
>> static unsigned int stdout_lines = STDOUT_HEADER_REPEAT;
>> +static bool stdout_header_repeat;
>>
>> static void
>> stdout_open_struct(const char *name)
>> @@ -1580,16 +1581,22 @@ static const struct print_operations term_pops = {
>>
>> static bool print_groups(struct cnt_group **groups)
>> {
>> - unsigned int headers = stdout_lines % STDOUT_HEADER_REPEAT + 1;
>> + static bool headers_printed = false;
> ----------------------------------- ^
> Remove this initialization (use checkpatch from Linux kernel).
>
> Please correct and resend (you can keep my r-b).
Fixed and pushed, thanks for the review!
Regards,
Tvrtko
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2023-02-09 8:25 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-03 11:16 [Intel-gfx] [PATCH i-g-t 0/3] More intel_gpu_top improvements Tvrtko Ursulin
2023-02-03 11:16 ` [Intel-gfx] [PATCH i-g-t 1/3] intel_gpu_top: Do not repeat header lines in non-interactive output Tvrtko Ursulin
2023-02-07 13:25 ` Kamil Konieczny
2023-02-08 12:31 ` Kamil Konieczny
2023-02-09 8:24 ` Tvrtko Ursulin
2023-02-03 11:16 ` [Intel-gfx] [PATCH i-g-t 2/3] intel_gpu_top: Rename STDOUT to TEXT Tvrtko Ursulin
2023-02-07 13:15 ` [Intel-gfx] [igt-dev] " Kamil Konieczny
2023-02-03 11:16 ` [Intel-gfx] [PATCH i-g-t 3/3] intel_gpu_top: Add CVS output format Tvrtko Ursulin
2023-02-03 11:22 ` [Intel-gfx] [igt-dev] " Ville Syrjälä
2023-02-03 11:27 ` Tvrtko Ursulin
2023-02-03 11:30 ` [Intel-gfx] [PATCH i-g-t 3/3] intel_gpu_top: Add CSV " Tvrtko Ursulin
2023-02-03 11:31 ` Tvrtko Ursulin
2023-02-07 13:29 ` Kamil Konieczny
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).