Skip to content

Commit da3cc6e

Browse files
duc0facebook-github-bot
authored andcommitted
Caffe2 - Add flag to fails if float point exceptions is detected in operator runs (pytorch#18040)
Summary: Pull Request resolved: pytorch#18040 Add flag to fails if float point exceptions is detected in operator runs Sample exception Exception [enforce fail at operator.h:837] !std::fetestexcept(FE_DIVBYZERO). Division by zero floating point exception (FE_DIVBYZERO) reported. Error from operator: input: "1" input: "0" output: "out" name: "" type: "Div" Reviewed By: jspark1105 Differential Revision: D14467731 fbshipit-source-id: fad030b1d619a5a661ff2114edb947e4562cecdd
1 parent 0fe6e8c commit da3cc6e

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

caffe2/core/operator.cc

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ C10_DEFINE_bool(
2525
false,
2626
"If set, disable implicit engine preferences. This is useful for unit "
2727
"testing and debugging cases.");
28+
C10_DEFINE_bool(
29+
caffe2_operator_throw_if_fp_exceptions,
30+
false,
31+
"If set, throws if floating point exceptions (FE_DIVBYZERO, FE_INVALID, "
32+
"FE_OVERFLOW) are detected when running any operator.");
2833

2934
namespace caffe2 {
3035

caffe2/core/operator.h

+18
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define CAFFE2_CORE_OPERATOR_H_
33

44
#include <array>
5+
#include <cfenv>
56
#include <climits>
67
#include <cstddef>
78
#include <exception>
@@ -27,6 +28,8 @@
2728
#include <ATen/core/function_schema.h>
2829
#include <ATen/core/ivalue.h>
2930

31+
C10_DECLARE_bool(caffe2_operator_throw_if_fp_exceptions);
32+
3033
namespace caffe2 {
3134

3235
class CAFFE2_API OperatorBase;
@@ -823,7 +826,22 @@ class Operator : public OperatorBase {
823826
StartAllObservers();
824827

825828
context_.SwitchToDevice(stream_id);
829+
830+
if (FLAGS_caffe2_operator_throw_if_fp_exceptions) {
831+
std::feclearexcept(FE_ALL_EXCEPT);
832+
}
826833
bool result = RunOnDevice();
834+
if (FLAGS_caffe2_operator_throw_if_fp_exceptions) {
835+
CAFFE_ENFORCE(
836+
!std::fetestexcept(FE_DIVBYZERO),
837+
"Division by zero floating point exception (FE_DIVBYZERO) reported.");
838+
CAFFE_ENFORCE(
839+
!std::fetestexcept(FE_INVALID),
840+
"Invalid floating point exception (FE_INVALID) reported.");
841+
CAFFE_ENFORCE(
842+
!std::fetestexcept(FE_OVERFLOW),
843+
"Overflow floating point exception (FE_OVERFLOW) reported.");
844+
}
827845
if (!result) {
828846
this->RecordLastFailedOpNetPosition();
829847
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from __future__ import absolute_import
2+
from __future__ import division
3+
from __future__ import print_function
4+
5+
from caffe2.python import core, workspace
6+
from caffe2.proto import caffe2_pb2
7+
from caffe2.python.test_util import TestCase
8+
9+
import numpy as np
10+
import unittest
11+
12+
13+
def setThrowIfFpExceptions(enabled):
14+
core.GlobalInit(["caffe2", "--caffe2_operator_throw_if_fp_exceptions=%d" % (1 if enabled else 0)])
15+
16+
17+
class OperatorFPExceptionsTest(TestCase):
18+
def test_fp_exception_divbyzero(self):
19+
# This test asserts the followings
20+
# - If flag caffe2_operator_throw_if_fp_exceptions is set,
21+
# floating point exceptions will be thrown
22+
# - If flag caffe2_operator_throw_if_fp_exceptions is not set,
23+
# floating point exceptions will not be thrown
24+
workspace.blobs["0"] = np.array([0.0], dtype=np.float32)
25+
workspace.blobs["1"] = np.array([1.0], dtype=np.float32)
26+
27+
net = core.Net("test_fp")
28+
net.Div(["1", "0"], "out")
29+
30+
for throw_if_fp_exceptions in (True, False):
31+
setThrowIfFpExceptions(throw_if_fp_exceptions)
32+
exception_raised = False
33+
try:
34+
workspace.RunNetOnce(net)
35+
except Exception as e:
36+
exception_raised = True
37+
self.assertEquals(exception_raised, throw_if_fp_exceptions)
38+
39+
40+
if __name__ == '__main__':
41+
unittest.main()

0 commit comments

Comments
 (0)