Skip to content

Commit 9bff046

Browse files
author
Diptorup Deb
committed
Add a new DPCTLExecState type to improve error handling.
- A new DPCTLExecState type and associated constructors and destructors are added. - The error_handler_callback is depracated and is superseded by the new error_handler_callback_fn type. The new function type allows passing in both an error code and an error message. - A default error handler function is defined that will print out an error code and optionally an associated error message, file name, func name, line number to std::cerr. - Renamed the dpctl_async_error_handler.{h|cpp} files to dpctl_error_handlers to include an implementation of the default error handler.
1 parent 49ded41 commit 9bff046

File tree

7 files changed

+315
-4
lines changed

7 files changed

+315
-4
lines changed

dpctl-capi/helper/include/dpctl_async_error_handler.h renamed to dpctl-capi/helper/include/dpctl_error_handlers.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,28 @@ class DPCTL_API DPCTL_AsyncErrorHandler
4444

4545
void operator()(const cl::sycl::exception_list &exceptions);
4646
};
47+
48+
/*!
49+
* @brief Provides a static error handling function that prints an error code
50+
* and message to the standard error stream.
51+
*
52+
*/
53+
class DPCTL_API DefaultErrorHandler
54+
{
55+
public:
56+
/*!
57+
* @brief A default error handler function that prints out the error code
58+
* and optionally the error message to ``std::cerr``.
59+
*
60+
* @param err_code An integer error code.
61+
* @param err_msg A C string corresponding to an error message.
62+
* @param file_name The file where the error occurred.
63+
* @param func_name The function name where the error occurred.
64+
* @param line_num The line number where the error occurred.
65+
*/
66+
static void handler(int err_code,
67+
const char *err_msg,
68+
const char *file_name,
69+
const char *func_name,
70+
int line_num);
71+
};

dpctl-capi/helper/source/dpctl_async_error_handler.cpp renamed to dpctl-capi/helper/source/dpctl_error_handlers.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
/// context and queue contructors.
2424
//===----------------------------------------------------------------------===//
2525

26-
#include "dpctl_async_error_handler.h"
26+
#include "dpctl_error_handlers.h"
27+
#include <iomanip>
28+
#include <iostream>
2729

2830
void DPCTL_AsyncErrorHandler::operator()(
2931
const cl::sycl::exception_list &exceptions)
@@ -40,3 +42,29 @@ void DPCTL_AsyncErrorHandler::operator()(
4042
}
4143
}
4244
}
45+
46+
void DefaultErrorHandler::handler(int err_code,
47+
const char *err_msg,
48+
const char *file_name,
49+
const char *func_name,
50+
int line_num)
51+
{
52+
std::stringstream ss;
53+
54+
ss << "Dpctl-Error ";
55+
if (file_name)
56+
ss << "on " << file_name << " ";
57+
58+
if (func_name)
59+
ss << "at " << func_name << " ";
60+
61+
if (line_num)
62+
ss << "on line " << line_num << ".";
63+
64+
ss << " (" << err_code << ")";
65+
66+
if (err_msg)
67+
ss << " " << err_msg << '\n';
68+
69+
std::cerr << ss.str();
70+
}

dpctl-capi/include/dpctl_error_handler_type.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,21 @@
3232
* @param err_code Error code extracted from an SYCL asynchronous
3333
* error.
3434
*/
35-
typedef void error_handler_callback(int err_code);
35+
typedef void error_handler_callback(int err_code) __attribute__((
36+
deprecated("the function does not allow passing in an error string, use "
37+
"'error_handler_callback_fn' instead!!!")));
38+
39+
/*!
40+
* @brief Type signature required for an error handler callback function.
41+
*
42+
* @param err_code An integer error code.
43+
* @param err_msg A C string corresponding to an error message.
44+
* @param file_name The file where the error occurred.
45+
* @param func_name The function name where the error occurred.
46+
* @param line_num The line number where the error occurred.
47+
*/
48+
typedef void (*error_handler_callback_fn)(int err_code,
49+
const char *err_msg,
50+
const char *file_name,
51+
const char *func_name,
52+
int line_num);
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
//===- dpctl_exec_state.h - C API for service functions -*-C++-*- ===//
2+
//
3+
// Data Parallel Control (dpctl)
4+
//
5+
// Copyright 2020-2021 Intel Corporation
6+
//
7+
// Licensed under the Apache License, Version 2.0 (the "License");
8+
// you may not use this file except in compliance with the License.
9+
// You may obtain a copy of the License at
10+
//
11+
// http://www.apache.org/licenses/LICENSE-2.0
12+
//
13+
// Unless required by applicable law or agreed to in writing, software
14+
// distributed under the License is distributed on an "AS IS" BASIS,
15+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
// See the License for the specific language governing permissions and
17+
// limitations under the License.
18+
//
19+
//===----------------------------------------------------------------------===//
20+
///
21+
/// \file
22+
/// The file declares a struct to store dpctl's error handler and other
23+
/// execution state configurations.
24+
///
25+
//===----------------------------------------------------------------------===//
26+
27+
#pragma once
28+
29+
#include "Support/DllExport.h"
30+
#include "Support/ExternC.h"
31+
#include "Support/MemOwnershipAttrs.h"
32+
#include "dpctl_error_handler_type.h"
33+
34+
DPCTL_C_EXTERN_C_BEGIN
35+
36+
/*!
37+
* @brief An opaque type to represent an "execution state" for the dpctl
38+
* sycl interface library.
39+
*
40+
* The execution state controls the behavior of functions exposed by
41+
* libDPCTLSyclInterface. For now, only error handling is controlled by an
42+
* execution state. Using a custom execution state, users can define how
43+
* exceptions in the C++ code are handled and propagated to callers. A default
44+
* execution state where all exceptions are caught and the error messages
45+
* printed to ``std::cerr`` is included for convenience.
46+
*
47+
*/
48+
typedef struct DpctlExecutionState *DpctlExecState;
49+
50+
/*!
51+
* @brief Create a new ``DpctlExecState`` object.
52+
*
53+
* @param handler An error handler function.
54+
* @return A ``DpctlExecState`` opaque pointer.
55+
*/
56+
__dpctl_give DpctlExecState
57+
dpctl_exec_state_create(error_handler_callback_fn handler);
58+
59+
/*!
60+
* @brief Create a default execution state that prints the error message to
61+
* ``std::cerr``.
62+
*
63+
* @return A ``DpctlExecState`` opaque pointer.
64+
*/
65+
__dpctl_give DpctlExecState dpctl_exec_state_create_default();
66+
67+
/*!
68+
* @brief Delete an ``DpctlExecState`` opaque pointer.
69+
*
70+
* @param DpctlExecState A ``DpctlExecState`` opaque pointer to be freed.
71+
*/
72+
void dpctl_exec_state_delete(__dpctl_take DpctlExecState state);
73+
74+
/*!
75+
* @brief Get the error handler defined in the ``DpctlExecState`` object.
76+
*
77+
* @param state An ``DpctlExecState`` object.
78+
* @return A error_handler_callback_fn function pointer that was stored inside
79+
* the DpctlExecState object.
80+
*/
81+
error_handler_callback_fn
82+
dpctl_exec_state_get_error_handler(__dpctl_keep DpctlExecState state);
83+
84+
/*!
85+
* @brief Call the error handler defined in the ``DpctlExecState`` object.
86+
*
87+
* @param state An ``DpctlExecState`` object.
88+
* @param err_code An integer error code.
89+
* @param err_msg A C string corresponding to an error message.
90+
* @param file_name The file where the error occurred.
91+
* @param func_name The function name where the error occurred.
92+
* @param line_num The line number where the error occurred.
93+
*/
94+
void dpctl_exec_state_handle_error(__dpctl_keep DpctlExecState state,
95+
int err_code,
96+
__dpctl_keep const char *err_msg,
97+
__dpctl_keep const char *file_name,
98+
__dpctl_keep const char *func_name,
99+
int line_num);
100+
101+
DPCTL_C_EXTERN_C_END
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
//===- dpctl_exec_state.cpp - Implements C API for sycl::context ---==//
2+
//
3+
// Data Parallel Control (dpctl)
4+
//
5+
// Copyright 2020-2021 Intel Corporation
6+
//
7+
// Licensed under the Apache License, Version 2.0 (the "License");
8+
// you may not use this file except in compliance with the License.
9+
// You may obtain a copy of the License at
10+
//
11+
// http://www.apache.org/licenses/LICENSE-2.0
12+
//
13+
// Unless required by applicable law or agreed to in writing, software
14+
// distributed under the License is distributed on an "AS IS" BASIS,
15+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
// See the License for the specific language governing permissions and
17+
// limitations under the License.
18+
//
19+
//===----------------------------------------------------------------------===//
20+
///
21+
/// \file
22+
/// This file implements the data types and functions declared in
23+
/// dpctl_exec_state.h.
24+
///
25+
//===----------------------------------------------------------------------===//
26+
27+
#include "dpctl_exec_state.h"
28+
#include "../helper/include/dpctl_error_handlers.h"
29+
#include "Support/CBindingWrapping.h"
30+
#include <iomanip>
31+
#include <iostream>
32+
33+
namespace
34+
{
35+
36+
/*!
37+
* @brief The execution state that is passed to every libDPCTLSyclInterface
38+
* function.
39+
*
40+
* The ``ExecutionState`` class is a concrete implementation of the
41+
* `DpctlExecState`` opaque type.
42+
*
43+
*/
44+
class ExecutionState
45+
{
46+
error_handler_callback_fn handler_;
47+
48+
public:
49+
/*!
50+
* @brief Construct a new ``ExecutionState`` object using the default error
51+
* handler object.
52+
*
53+
*/
54+
ExecutionState() : handler_(DefaultErrorHandler::handler){};
55+
/*!
56+
* @brief Construct a new ``ExecutionState`` object with the provided error
57+
* handler function.
58+
*
59+
* @param handler Error handler function to be used by the
60+
* instance of ``ExecutionState``.
61+
*/
62+
explicit ExecutionState(error_handler_callback_fn handler)
63+
: handler_(handler)
64+
{
65+
}
66+
67+
void operator()(int err_code,
68+
const char *err_msg,
69+
const char *file_name,
70+
const char *func_name,
71+
int line_num) const
72+
{
73+
handler_(err_code, err_msg, file_name, func_name, line_num);
74+
}
75+
76+
error_handler_callback_fn get_handler() const
77+
{
78+
return handler_;
79+
}
80+
};
81+
82+
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionState, DpctlExecState);
83+
84+
} // namespace
85+
86+
__dpctl_give DpctlExecState
87+
dpctl_exec_state_create(error_handler_callback_fn handler)
88+
{
89+
try {
90+
ExecutionState *state = new ExecutionState(handler);
91+
return wrap(state);
92+
} catch (std::bad_alloc const &ba) {
93+
std::cerr << ba.what() << '\n';
94+
std::terminate();
95+
}
96+
}
97+
98+
__dpctl_give DpctlExecState dpctl_exec_state_create_default()
99+
{
100+
try {
101+
ExecutionState *state = new ExecutionState();
102+
return wrap(state);
103+
} catch (std::bad_alloc const &ba) {
104+
std::cerr << ba.what() << '\n';
105+
std::terminate();
106+
}
107+
}
108+
109+
void dpctl_exec_state_delete(__dpctl_take DpctlExecState state)
110+
{
111+
delete unwrap(state);
112+
}
113+
114+
error_handler_callback_fn
115+
dpctl_exec_state_get_error_handler(__dpctl_keep DpctlExecState state)
116+
{
117+
auto ES = unwrap(state);
118+
if (!ES) {
119+
std::cerr << "Execution state is corrupted. Abort!\n";
120+
std::terminate();
121+
}
122+
123+
return ES->get_handler();
124+
}
125+
126+
void dpctl_exec_state_handle_error(__dpctl_keep DpctlExecState state,
127+
int err_code,
128+
__dpctl_keep const char *err_msg,
129+
__dpctl_keep const char *file_name,
130+
__dpctl_keep const char *func_name,
131+
int line_num)
132+
{
133+
auto ES = unwrap(state);
134+
if (!ES) {
135+
std::cerr << "Execution state is corrupted. Abort!\n";
136+
std::terminate();
137+
}
138+
139+
(*ES)(err_code, err_msg, file_name, func_name, line_num);
140+
}

dpctl-capi/source/dpctl_sycl_context_interface.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
//===----------------------------------------------------------------------===//
2626

2727
#include "dpctl_sycl_context_interface.h"
28-
#include "../helper/include/dpctl_async_error_handler.h"
28+
#include "../helper/include/dpctl_error_handlers.h"
2929
#include "Support/CBindingWrapping.h"
3030
#include <CL/sycl.hpp>
3131
#include <vector>

dpctl-capi/source/dpctl_sycl_queue_interface.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
//===----------------------------------------------------------------------===//
2626

2727
#include "dpctl_sycl_queue_interface.h"
28-
#include "../helper/include/dpctl_async_error_handler.h"
28+
#include "../helper/include/dpctl_error_handlers.h"
2929
#include "Support/CBindingWrapping.h"
3030
#include "dpctl_sycl_context_interface.h"
3131
#include "dpctl_sycl_device_interface.h"

0 commit comments

Comments
 (0)