Skip to content

Commit

Permalink
Add printing C API
Browse files Browse the repository at this point in the history
Add a shared library for printing Unified Runtime objects with a C API.
  • Loading branch information
PatKamin committed Oct 10, 2023
1 parent cbc9f53 commit ce43934
Show file tree
Hide file tree
Showing 13 changed files with 5,632 additions and 397 deletions.
4 changes: 3 additions & 1 deletion scripts/core/INTRO.rst
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,13 @@ Printing API
## --validate=off
The header "${x}_print.hpp" contains the "${x}_print" namespace with the output stream operator (<<) overloads. These are helpful for a human-friendly print
of the Unified Runtime objects.

There is also the "${x}FunctionParamsPrint" function for printing function parameters. These parameters have to be provided in a \*params_t struct format suitable for
a given function.

The ${x}_print.h header provides the same functionality with a C interface.
## --validate=on


Tracing
---------------------

Expand Down
50 changes: 50 additions & 0 deletions scripts/generate_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,44 @@ def _mako_ddi_h(path, namespace, tags, version, revision, specs, meta):
specs=specs,
meta=meta)

"""
generates c/c++ files from the mako template
"""
def _mako_print_h(path, namespace, tags, version, specs, meta):
template = "print.h.mako"
fin = os.path.join("templates", template)

filename = "%s_print.h"%(namespace)
fout = os.path.join(path, filename)

print("Generating %s..."%fout)
return util.makoWrite(
fin, fout,
ver=version,
namespace=namespace,
tags=tags,
specs=specs,
meta=meta)

"""
generates c/c++ files from the mako template
"""
def _mako_print_cpp(path, namespace, tags, version, specs, meta):
template = "print.cpp.mako"
fin = os.path.join("templates", template)

filename = "%s_print.cpp"%(namespace)
fout = os.path.join(path, filename)

print("Generating %s..."%fout)
return util.makoWrite(
fin, fout,
ver=version,
namespace=namespace,
tags=tags,
specs=specs,
meta=meta)

"""
generates python files from the specification documents
"""
Expand Down Expand Up @@ -354,6 +392,18 @@ def generate_layers(path, section, namespace, tags, version, specs, meta):
loc += _mako_tracing_layer_cpp(layer_dstpath, namespace, tags, version, specs, meta)
print("TRACING Generated %s lines of code.\n"%loc)

"""
Entry-point:
generates objects printing API for unified_runtime
"""
def generate_print_api(path, namespace, tags, version, specs, meta):
print_dstpath = os.path.join(path, "source", "print")

loc = 0
loc += _mako_print_h(print_dstpath, namespace, tags, version, specs, meta)
loc += _mako_print_cpp(print_dstpath, namespace, tags, version, specs, meta)
print("PRINT Generated %s lines of code.\n"%loc)

"""
Entry-point:
generates common utilities for unified_runtime
Expand Down
11 changes: 11 additions & 0 deletions scripts/templates/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,17 @@ def make_func_name(namespace, tags, obj):
cname = ''
return subt(namespace, tags, "%s%s"%(cname, obj['name']))

"""
Public:
returns the name of a function from a given name with prefix
"""
def make_func_name_with_prefix(prefix, name):
func_name = re.sub(r'^[^_]+_', '', name)
func_name = re.sub('_t$', '', func_name).capitalize()
func_name = re.sub(r'_([a-z])', lambda match: match.group(1).upper(), func_name)
func_name = f'{prefix}{func_name}'
return func_name

"""
Public:
returns the etor of a function
Expand Down
91 changes: 91 additions & 0 deletions scripts/templates/print.cpp.mako
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<%!
import re
from templates import helper as th
%><%
n=namespace
N=n.upper()
x=tags['$x']
X=x.upper()
%>/*
*
* Copyright (C) 2023 Intel Corporation
*
* Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
* See LICENSE.TXT
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
* @file ${n}_print.cpp
*
*/

#include "${n}_print.h"
#include "${n}_print.hpp"

#include <sstream>
#include <string.h>

using namespace ${x}_print;

<%def name="ss_copy(item_name)">std::stringstream ss;
ss << ${item_name};
strncpy(&ss, out, size);
</%def>

void strncpy(std::stringstream *ss, char *out, const size_t size) {
#if defined(_WIN32)
strncpy_s(out, size, ss->str().c_str(), ss->str().size() + 1);
#else
strncpy(out, ss->str().c_str(), size);
#endif
}

%for spec in specs:
%for obj in spec['objects']:
## ENUM #######################################################################
%if re.match(r"enum", obj['type']):
ur_result_t ${th.make_func_name_with_prefix('urPrint', obj['name'])}(enum ${th.make_enum_name(n, tags, obj)} value, char *out, const size_t size) {
${ss_copy("value")}
return ${X}_RESULT_SUCCESS;
}

## STRUCT #####################################################################
%elif re.match(r"struct", obj['type']):
ur_result_t ${th.make_func_name_with_prefix('urPrint', obj['name'])}(const ${obj['type']} ${th.make_type_name(n, tags, obj)} params, char *out, const size_t size) {
${ss_copy("params")}
return ${X}_RESULT_SUCCESS;
}

%endif
%endfor # obj in spec['objects']
%endfor

%for tbl in th.get_pfncbtables(specs, meta, n, tags):
%for obj in tbl['functions']:
<%
name = th.make_pfncb_param_type(n, tags, obj)
%>
ur_result_t ${th.make_func_name_with_prefix('urPrint', name)}(const struct ${th.make_pfncb_param_type(n, tags, obj)} *params, char *out, const size_t size) {
${ss_copy("params")}
return ${X}_RESULT_SUCCESS;
}

%endfor
%endfor

ur_result_t urPrintFunctionParams(enum ur_function_t function, const void *params, char *out, const size_t size) {
std::stringstream ss;
switch(function) {
%for tbl in th.get_pfncbtables(specs, meta, n, tags):
%for obj in tbl['functions']:
case ${th.make_func_etor(n, tags, obj)}: {
ss << (const struct ${th.make_pfncb_param_type(n, tags, obj)} *)params;
strncpy(&ss, out, size);
return ${X}_RESULT_SUCCESS;
}
%endfor
%endfor
default:
return ${X}_RESULT_SUCCESS;
}
}
56 changes: 56 additions & 0 deletions scripts/templates/print.h.mako
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<%!
import re
from templates import helper as th
%><%
n=namespace
N=n.upper()
x=tags['$x']
X=x.upper()
%>/*
*
* Copyright (C) 2023 Intel Corporation
*
* Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
* See LICENSE.TXT
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
* @file ${n}_print.h
*
*/
#ifndef ${X}_PRINT_H
#define ${X}_PRINT_H 1

#include "${x}_api.h"

#if defined(__cplusplus)
extern "C" {
#endif

## Declarations ###############################################################
%for spec in specs:
%for obj in spec['objects']:
%if re.match(r"(enum)", obj['type']):
UR_DLLEXPORT ur_result_t UR_APICALL ${th.make_func_name_with_prefix('urPrint', obj['name'])}(enum ${th.make_enum_name(n, tags, obj)} value, char *out, const size_t size);
%elif re.match(r"struct", obj['type']):
UR_DLLEXPORT ur_result_t UR_APICALL ${th.make_func_name_with_prefix('urPrint', obj['name'])}(const ${obj['type']} ${th.make_type_name(n, tags, obj)} params, char *out, const size_t size);
%endif
%endfor # obj in spec['objects']
%endfor

%for tbl in th.get_pfncbtables(specs, meta, n, tags):
%for obj in tbl['functions']:
<%
name = th.make_pfncb_param_type(n, tags, obj)
%>
UR_DLLEXPORT ur_result_t UR_APICALL ${th.make_func_name_with_prefix('urPrint', name)}(const struct ${th.make_pfncb_param_type(n, tags, obj)} *params, char *out, const size_t size);
%endfor
%endfor

UR_DLLEXPORT ur_result_t UR_APICALL urPrintFunctionParams(enum ur_function_t function, const void *params, char *out, const size_t size);

#if defined(__cplusplus)
} // extern "C"
#endif

#endif /* ${X}_PRINT_H */
1 change: 1 addition & 0 deletions source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ add_subdirectory(common)
add_subdirectory(loader)
#add_subdirectory(layers)
add_subdirectory(adapters)
add_subdirectory(print)
31 changes: 31 additions & 0 deletions source/print/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright (C) 2023 Intel Corporation
# Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
# See LICENSE.TXT
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

set(TARGET_NAME ur_print)

add_ur_library(${TARGET_NAME} SHARED
ur_print.h
ur_print.cpp
)
add_library(${PROJECT_NAME}::print ALIAS ur_print)

target_link_libraries(${TARGET_NAME} PRIVATE
${PROJECT_NAME}::headers
)

target_include_directories(${TARGET_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:source/print>
)

install(TARGETS ${TARGET_NAME}
EXPORT ${PROJECT_NAME}-targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT unified-runtime
)

install(FILES ur_print.h
DESTINATION include)
Loading

0 comments on commit ce43934

Please sign in to comment.