cpu_debugger.cpp 13.6 KB
Newer Older
Nick Korovaiko's avatar
Nick Korovaiko committed
1
//*****************************************************************************
2
// Copyright 2017-2019 Intel Corporation
Nick Korovaiko's avatar
Nick Korovaiko committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//*****************************************************************************

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <list>
#include <memory>

#include "gtest/gtest.h"
#include "ngraph/autodiff/adjoints.hpp"
#include "ngraph/file_util.hpp"
#include "ngraph/graph_util.hpp"
#include "ngraph/log.hpp"
#include "ngraph/ngraph.hpp"
#include "ngraph/runtime/cpu/cpu_backend.hpp"
#include "ngraph/runtime/cpu/cpu_call_frame.hpp"
#include "ngraph/runtime/cpu/cpu_debugger.hpp"
#include "ngraph/runtime/cpu/cpu_layout_descriptor.hpp"
#include "ngraph/runtime/cpu/cpu_tensor_view.hpp"
#include "ngraph/runtime/cpu/op/sigmoid_mul.hpp"
#include "ngraph/util.hpp"
#include "util/test_tools.hpp"

using namespace ngraph;
using namespace std;

41 42
bool static is_codegen_mode()
{
43 44 45
    static bool codegen_set = false;
    static bool codegen_mode = false;
    if (!codegen_set)
46
    {
47 48 49
        const char* ngraph_codegen = std::getenv("NGRAPH_CODEGEN");
        codegen_mode = (ngraph_codegen != nullptr) && std::string(ngraph_codegen) != "0";
        codegen_set = true;
50
    }
51
    return codegen_mode;
52 53 54
}

// These tests are for DEX mode only.
55
TEST(debugger, MLIR_DISABLE_TEST(add_breakpoint))
Nick Korovaiko's avatar
Nick Korovaiko committed
56
{
57 58
    if (is_codegen_mode())
    {
59
        // TODO change to skip when there is a new release of gtest
60 61 62 63
        NGRAPH_WARN << "This test is skipped for CODEGEN mode.";
        return;
    }

Nick Korovaiko's avatar
Nick Korovaiko committed
64 65 66 67 68 69 70 71
    Shape shape{};
    auto A = make_shared<op::Parameter>(element::i32, shape);
    auto B = make_shared<op::Parameter>(element::i32, shape);

    auto add = make_shared<op::Add>(A, B);
    auto absn = make_shared<op::Abs>(add);
    auto neg = make_shared<op::Negative>(absn);

72
    auto f = make_shared<Function>(neg, ParameterVector{A, B});
Nick Korovaiko's avatar
Nick Korovaiko committed
73

74
    shared_ptr<runtime::Backend> backend = runtime::Backend::create("CPU");
Nick Korovaiko's avatar
Nick Korovaiko committed
75 76 77 78 79 80 81 82 83 84

    shared_ptr<runtime::Tensor> a = backend->create_tensor(element::i32, shape);
    shared_ptr<runtime::Tensor> b = backend->create_tensor(element::i32, shape);
    shared_ptr<runtime::Tensor> result = backend->create_tensor(element::i32, shape);

    vector<int> dataA{-1};
    vector<int> dataB{-776};
    copy_data(a, dataA);
    copy_data(b, dataB);

Robert Kimball's avatar
Robert Kimball committed
85 86
    shared_ptr<runtime::Executable> handle = backend->compile(f);
    auto cf = dynamic_pointer_cast<runtime::cpu::CPU_Executable>(handle)->get_call_frame();
Nick Korovaiko's avatar
Nick Korovaiko committed
87 88 89 90 91

    ngraph::runtime::cpu::CPU_Debugger dbg(*cf);

    dbg.add_breakpoint(neg);
    dbg.call({result}, {a, b});
92

Nick Korovaiko's avatar
Nick Korovaiko committed
93 94 95 96 97 98
    ASSERT_EQ(*static_cast<int*>(dbg.inspect(add)), -777);
    ASSERT_EQ(*static_cast<int*>(dbg.inspect(absn)), 777);
    dbg.step();
    ASSERT_EQ(*static_cast<int*>(dbg.inspect(neg)), -777);
}

99
TEST(debugger, MLIR_DISABLE_TEST(stepping))
Nick Korovaiko's avatar
Nick Korovaiko committed
100
{
101 102
    if (is_codegen_mode())
    {
103
        // TODO change to skip when there is a new release of gtest
104 105 106 107
        NGRAPH_WARN << "This test is skipped for CODEGEN mode.";
        return;
    }

Nick Korovaiko's avatar
Nick Korovaiko committed
108 109 110 111 112 113 114 115
    Shape shape{};
    auto A = make_shared<op::Parameter>(element::i32, shape);
    auto B = make_shared<op::Parameter>(element::i32, shape);

    auto add = make_shared<op::Add>(A, B);
    auto absn = make_shared<op::Abs>(add);
    auto neg = make_shared<op::Negative>(absn);

116
    auto f = make_shared<Function>(neg, ParameterVector{A, B});
Nick Korovaiko's avatar
Nick Korovaiko committed
117

118
    shared_ptr<runtime::Backend> backend = runtime::Backend::create("CPU");
Nick Korovaiko's avatar
Nick Korovaiko committed
119 120 121 122 123 124 125 126 127 128

    shared_ptr<runtime::Tensor> a = backend->create_tensor(element::i32, shape);
    shared_ptr<runtime::Tensor> b = backend->create_tensor(element::i32, shape);
    shared_ptr<runtime::Tensor> result = backend->create_tensor(element::i32, shape);

    vector<int> dataA{-1};
    vector<int> dataB{-776};
    copy_data(a, dataA);
    copy_data(b, dataB);

Robert Kimball's avatar
Robert Kimball committed
129 130
    shared_ptr<runtime::Executable> handle = backend->compile(f);
    auto cf = dynamic_pointer_cast<runtime::cpu::CPU_Executable>(handle)->get_call_frame();
Nick Korovaiko's avatar
Nick Korovaiko committed
131 132 133 134 135

    ngraph::runtime::cpu::CPU_Debugger dbg(*cf);

    dbg.add_breakpoint(add);
    dbg.call({result}, {a, b});
136

Nick Korovaiko's avatar
Nick Korovaiko committed
137 138 139 140 141 142 143
    ASSERT_EQ(*static_cast<int*>(dbg.inspect(add)), -777);
    dbg.step();
    ASSERT_EQ(*static_cast<int*>(dbg.inspect(absn)), 777);
    dbg.step();
    ASSERT_EQ(*static_cast<int*>(dbg.inspect(neg)), -777);
}

144
TEST(debugger, MLIR_DISABLE_TEST(delete_breakpoint))
Nick Korovaiko's avatar
Nick Korovaiko committed
145
{
146 147
    if (is_codegen_mode())
    {
148
        // TODO change to skip when there is new release of gtest
149 150 151 152
        NGRAPH_WARN << "This test is skipped for CODEGEN mode.";
        return;
    }

Nick Korovaiko's avatar
Nick Korovaiko committed
153 154 155 156 157 158 159 160
    Shape shape{};
    auto A = make_shared<op::Parameter>(element::i32, shape);
    auto B = make_shared<op::Parameter>(element::i32, shape);

    auto add = make_shared<op::Add>(A, B);
    auto absn = make_shared<op::Abs>(add);
    auto neg = make_shared<op::Negative>(absn);

161
    auto f = make_shared<Function>(neg, ParameterVector{A, B});
Nick Korovaiko's avatar
Nick Korovaiko committed
162

163
    shared_ptr<runtime::Backend> backend = runtime::Backend::create("CPU");
Nick Korovaiko's avatar
Nick Korovaiko committed
164 165 166 167 168 169 170 171 172 173

    shared_ptr<runtime::Tensor> a = backend->create_tensor(element::i32, shape);
    shared_ptr<runtime::Tensor> b = backend->create_tensor(element::i32, shape);
    shared_ptr<runtime::Tensor> result = backend->create_tensor(element::i32, shape);

    vector<int> dataA{-1};
    vector<int> dataB{-776};
    copy_data(a, dataA);
    copy_data(b, dataB);

Robert Kimball's avatar
Robert Kimball committed
174 175
    shared_ptr<runtime::Executable> handle = backend->compile(f);
    auto cf = dynamic_pointer_cast<runtime::cpu::CPU_Executable>(handle)->get_call_frame();
Nick Korovaiko's avatar
Nick Korovaiko committed
176 177 178 179 180 181 182 183 184 185

    ngraph::runtime::cpu::CPU_Debugger dbg(*cf);

    dbg.add_breakpoint(add);
    dbg.add_breakpoint(absn);
    dbg.add_breakpoint(neg);
    dbg.delete_breakpoint(add);
    dbg.delete_breakpoint(absn);
    dbg.delete_breakpoint(neg);
    dbg.call({result}, {a, b});
186

Nick Korovaiko's avatar
Nick Korovaiko committed
187 188 189 190 191
    ASSERT_EQ(*static_cast<int*>(dbg.inspect(add)), -777);
    ASSERT_EQ(*static_cast<int*>(dbg.inspect(absn)), 777);
    ASSERT_EQ(*static_cast<int*>(dbg.inspect(neg)), -777);
}

192
TEST(debugger, MLIR_DISABLE_TEST(while_stepping))
Nick Korovaiko's avatar
Nick Korovaiko committed
193
{
194 195
    if (is_codegen_mode())
    {
196
        // TODO change to skip when there is new release of gtest
197 198 199 200
        NGRAPH_WARN << "This test is skipped for CODEGEN mode.";
        return;
    }

Nick Korovaiko's avatar
Nick Korovaiko committed
201 202 203 204 205 206 207 208
    Shape shape{};
    auto A = make_shared<op::Parameter>(element::i32, shape);
    auto B = make_shared<op::Parameter>(element::i32, shape);

    auto add = make_shared<op::Add>(A, B);
    auto absn = make_shared<op::Abs>(add);
    auto neg = make_shared<op::Negative>(absn);

209
    auto f = make_shared<Function>(neg, ParameterVector{A, B});
Nick Korovaiko's avatar
Nick Korovaiko committed
210

211
    shared_ptr<runtime::Backend> backend = runtime::Backend::create("CPU");
Nick Korovaiko's avatar
Nick Korovaiko committed
212 213 214 215 216 217 218 219 220 221

    shared_ptr<runtime::Tensor> a = backend->create_tensor(element::i32, shape);
    shared_ptr<runtime::Tensor> b = backend->create_tensor(element::i32, shape);
    shared_ptr<runtime::Tensor> result = backend->create_tensor(element::i32, shape);

    vector<int> dataA{-1};
    vector<int> dataB{-776};
    copy_data(a, dataA);
    copy_data(b, dataB);

Robert Kimball's avatar
Robert Kimball committed
222 223
    shared_ptr<runtime::Executable> handle = backend->compile(f);
    auto cf = dynamic_pointer_cast<runtime::cpu::CPU_Executable>(handle)->get_call_frame();
Nick Korovaiko's avatar
Nick Korovaiko committed
224 225 226 227 228 229 230

    ngraph::runtime::cpu::CPU_Debugger dbg(*cf);

    dbg.call({result}, {a, b});
    dbg.add_breakpoint(add);
    while (dbg.step())
    {
231
    }
232

Nick Korovaiko's avatar
Nick Korovaiko committed
233 234 235 236 237
    ASSERT_EQ(*static_cast<int*>(dbg.inspect(add)), -777);
    ASSERT_EQ(*static_cast<int*>(dbg.inspect(absn)), 777);
    ASSERT_EQ(*static_cast<int*>(dbg.inspect(neg)), -777);
}

238
TEST(debugger, MLIR_DISABLE_TEST(resume))
Nick Korovaiko's avatar
Nick Korovaiko committed
239
{
240 241
    if (is_codegen_mode())
    {
242
        // TODO change to skip when there is new release of gtest
243 244 245 246
        NGRAPH_WARN << "This test is skipped for CODEGEN mode.";
        return;
    }

Nick Korovaiko's avatar
Nick Korovaiko committed
247 248 249 250 251 252 253 254
    Shape shape{};
    auto A = make_shared<op::Parameter>(element::i32, shape);
    auto B = make_shared<op::Parameter>(element::i32, shape);

    auto add = make_shared<op::Add>(A, B);
    auto absn = make_shared<op::Abs>(add);
    auto neg = make_shared<op::Negative>(absn);

255
    auto f = make_shared<Function>(neg, ParameterVector{A, B});
Nick Korovaiko's avatar
Nick Korovaiko committed
256

257
    shared_ptr<runtime::Backend> backend = runtime::Backend::create("CPU");
Nick Korovaiko's avatar
Nick Korovaiko committed
258 259 260 261 262 263 264 265 266 267

    shared_ptr<runtime::Tensor> a = backend->create_tensor(element::i32, shape);
    shared_ptr<runtime::Tensor> b = backend->create_tensor(element::i32, shape);
    shared_ptr<runtime::Tensor> result = backend->create_tensor(element::i32, shape);

    vector<int> dataA{-1};
    vector<int> dataB{-776};
    copy_data(a, dataA);
    copy_data(b, dataB);

Robert Kimball's avatar
Robert Kimball committed
268 269
    shared_ptr<runtime::Executable> handle = backend->compile(f);
    auto cf = dynamic_pointer_cast<runtime::cpu::CPU_Executable>(handle)->get_call_frame();
Nick Korovaiko's avatar
Nick Korovaiko committed
270 271 272 273 274

    ngraph::runtime::cpu::CPU_Debugger dbg(*cf);

    dbg.add_breakpoint(absn);
    dbg.call({result}, {a, b});
275

Nick Korovaiko's avatar
Nick Korovaiko committed
276 277 278 279 280
    ASSERT_EQ(*static_cast<int*>(dbg.inspect(add)), -777);
    dbg.resume();
    ASSERT_EQ(*static_cast<int*>(dbg.inspect(absn)), 777);
    ASSERT_EQ(*static_cast<int*>(dbg.inspect(neg)), -777);
}
281

282
TEST(tracer, MLIR_DISABLE_TEST(basic))
283 284 285 286 287 288 289 290 291
{
    Shape shape{};
    auto A = make_shared<op::Parameter>(element::i32, shape);
    auto B = make_shared<op::Parameter>(element::i32, shape);

    auto add = make_shared<op::Add>(A, B);
    auto absn = make_shared<op::Abs>(add);
    auto neg = make_shared<op::Negative>(absn);

292
    auto f = make_shared<Function>(neg, ParameterVector{A, B});
293 294 295 296 297 298 299 300 301 302 303 304

    shared_ptr<runtime::Backend> backend = runtime::Backend::create("CPU");

    shared_ptr<runtime::Tensor> a = backend->create_tensor(element::i32, shape);
    shared_ptr<runtime::Tensor> b = backend->create_tensor(element::i32, shape);
    shared_ptr<runtime::Tensor> result = backend->create_tensor(element::i32, shape);

    vector<int> dataA{-1};
    vector<int> dataB{-776};
    copy_data(a, dataA);
    copy_data(b, dataB);

Robert Kimball's avatar
Robert Kimball committed
305 306
    shared_ptr<runtime::Executable> handle = backend->compile(f);
    auto cf = dynamic_pointer_cast<runtime::cpu::CPU_Executable>(handle)->get_call_frame();
307 308 309 310

    ngraph::runtime::cpu::CPU_Debugger dbg(*cf);

    int good_or_bad_value = -777;
311
    auto add_tracer = [&good_or_bad_value](void** values, const std::string& /* name */) {
312 313 314 315 316 317 318 319 320 321
        ASSERT_EQ(static_cast<int*>(values[0])[0], good_or_bad_value);
    };

    dbg.add_tracepoint(add, add_tracer);
    dbg.call({result}, {a, b});
    dbg.delete_tracepoint(add);
    good_or_bad_value = 777;
    dbg.call({result}, {a, b});
}

322
TEST(tracer, MLIR_DISABLE_TEST(count_tracepoint))
323 324 325 326 327 328 329
{
    Shape shape{};
    auto A = make_shared<op::Parameter>(element::i32, shape);
    auto B = make_shared<op::Parameter>(element::i32, shape);

    auto add = make_shared<op::Add>(A, B);

330
    auto f = make_shared<Function>(add, ParameterVector{A, B});
331 332 333 334 335 336 337

    shared_ptr<runtime::Backend> backend = runtime::Backend::create("CPU");

    shared_ptr<runtime::Tensor> a = backend->create_tensor(element::i32, shape);
    shared_ptr<runtime::Tensor> b = backend->create_tensor(element::i32, shape);
    shared_ptr<runtime::Tensor> result = backend->create_tensor(element::i32, shape);

Robert Kimball's avatar
Robert Kimball committed
338 339
    shared_ptr<runtime::Executable> handle = backend->compile(f);
    auto cf = dynamic_pointer_cast<runtime::cpu::CPU_Executable>(handle)->get_call_frame();
340 341 342

    ngraph::runtime::cpu::CPU_Debugger dbg(*cf);

343 344
    size_t num_iterations = 10;
    size_t offset = 5;
345 346

    std::function<void(void**, const std::string&)> callback =
347
        [&num_iterations, offset](void** values, const std::string& /* name */) {
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
            ASSERT_EQ(static_cast<int*>(values[0])[0], num_iterations - 1 + offset);
        };

    ngraph::runtime::cpu::CPU_CountTracepoint count_tracepoint(callback, 10);
    for (size_t i = 0; i < num_iterations; i++)
    {
        dbg.add_tracepoint(add, count_tracepoint);
        vector<int> dataA{static_cast<int>(offset)};
        vector<int> dataB{static_cast<int>(i)};
        copy_data(a, dataA);
        copy_data(b, dataB);
        dbg.call({result}, {a, b});
    }
}

363
TEST(tracer, MLIR_DISABLE_TEST(conditional_tracepoint))
364 365 366 367 368 369 370
{
    Shape shape{};
    auto A = make_shared<op::Parameter>(element::i32, shape);
    auto B = make_shared<op::Parameter>(element::i32, shape);

    auto add = make_shared<op::Add>(A, B);

371
    auto f = make_shared<Function>(add, ParameterVector{A, B});
372 373 374 375 376 377 378

    shared_ptr<runtime::Backend> backend = runtime::Backend::create("CPU");

    shared_ptr<runtime::Tensor> a = backend->create_tensor(element::i32, shape);
    shared_ptr<runtime::Tensor> b = backend->create_tensor(element::i32, shape);
    shared_ptr<runtime::Tensor> result = backend->create_tensor(element::i32, shape);

Robert Kimball's avatar
Robert Kimball committed
379 380
    shared_ptr<runtime::Executable> handle = backend->compile(f);
    auto cf = dynamic_pointer_cast<runtime::cpu::CPU_Executable>(handle)->get_call_frame();
381 382 383

    ngraph::runtime::cpu::CPU_Debugger dbg(*cf);

384 385
    size_t num_iterations = 10;
    size_t offset = 5;
386 387
    int countdown = num_iterations;

388 389
    auto add_tracer = [&countdown, num_iterations, offset](void** values,
                                                           const std::string& /* name */) {
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
        if (countdown-- == 0)
        {
            ASSERT_EQ(static_cast<int*>(values[0])[0], num_iterations - 1 + offset);
        }
    };

    for (size_t i = 0; i < num_iterations; i++)
    {
        dbg.add_tracepoint(add, add_tracer);
        vector<int> dataA{static_cast<int>(offset)};
        vector<int> dataB{static_cast<int>(i)};
        copy_data(a, dataA);
        copy_data(b, dataB);
        dbg.call({result}, {a, b});
    }
}