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 24, 2023
1 parent a2d23dc commit ee7ffb2
Show file tree
Hide file tree
Showing 13 changed files with 5,869 additions and 396 deletions.
2 changes: 2 additions & 0 deletions scripts/core/INTRO.rst
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ Printing API
The header "${x}_print.hpp" contains the "${x}::print" namespace with the output stream operator (<<) overloads for Unified Runtime objects.
There is also the "${x}::extras::printFunctionParams" 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
43 changes: 43 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 @@ -113,10 +151,15 @@ def _generate_api_py(incpath, namespace, tags, version, revision, specs, meta):
generates api code
"""
def generate_api(incpath, srcpath, namespace, tags, version, revision, specs, meta):
printpath = os.path.join(srcpath, "print")
util.makePath(incpath)
util.makePath(srcpath)
util.makePath(printpath)

loc = 0
loc += _mako_print_h(printpath, namespace, tags, version, specs, meta)
loc += _mako_print_cpp(printpath, namespace, tags, version, specs, meta)

loc += _generate_api_cpp(incpath, srcpath, namespace, tags, version, revision, specs, meta)
loc += _generate_api_py(incpath, namespace, tags, version, revision, specs, meta)
print("Generated %s lines of code.\n"%loc)
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
96 changes: 96 additions & 0 deletions scripts/templates/print.cpp.mako
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<%!
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 <algorithm>
#include <sstream>
#include <string.h>

using namespace ${x}::print;

<%def name="ss_copy(item_name)">std::stringstream ss;
ss << ${item_name};
str_copy(&ss, buff, buff_size, out_size);
</%def>

void str_copy(std::stringstream *ss, char *buff, const size_t buff_size, size_t *out_size) {
size_t c_str_size = strlen(ss->str().c_str()) + 1;
if (out_size) {
*out_size = c_str_size;
}
#if defined(_WIN32)
strncpy_s(buff, buff_size, ss->str().c_str(), c_str_size);
#else
strncpy(buff, ss->str().c_str(), std::min(buff_size, 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 *buff, const size_t buff_size, size_t *out_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 *buff, const size_t buff_size, size_t *out_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 *buff, const size_t buff_size, size_t *out_size) {
${ss_copy("params")}
return ${X}_RESULT_SUCCESS;
}

%endfor
%endfor

ur_result_t urPrintFunctionParams(enum ur_function_t function, const void *params, char *buff, const size_t buff_size, size_t *out_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;
str_copy(&ss, buff, buff_size, 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_APIEXPORT ur_result_t UR_APICALL ${th.make_func_name_with_prefix('urPrint', obj['name'])}(enum ${th.make_enum_name(n, tags, obj)} value, char *buffer, const size_t buff_size, size_t *out_size);
%elif re.match(r"struct", obj['type']):
UR_APIEXPORT 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 *buffer, const size_t buff_size, size_t *out_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_APIEXPORT 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 *buffer, const size_t buff_size, size_t *out_size);
%endfor
%endfor

UR_APIEXPORT ur_result_t UR_APICALL urPrintFunctionParams(enum ur_function_t function, const void *params, char *buffer, const size_t buff_size, size_t *out_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 ee7ffb2

Please sign in to comment.