Coverage Report

Created: 2017-11-12 13:27

/home/liu/buildslave/linux-x64-runtests/build/test/unit/nnc/symbolic.graph.tests.c
Line
Count
Source
1
#include "case.h"
2
#include "ccv_case.h"
3
#include "ccv_nnc_case.h"
4
#include <ccv.h>
5
#include <nnc/ccv_nnc.h>
6
#include <nnc/ccv_nnc_easy.h>
7
#include "3rdparty/dsfmt/dSFMT.h"
8
9
TEST_SETUP()
10
{
11
  ccv_nnc_init();
12
}
13
14
TEST_CASE("compile symbolic graph of one node")
15
1
{
16
1
  ccv_nnc_symbolic_graph_t* symbolic_graph = ccv_nnc_symbolic_graph_new();
17
1
  ccv_nnc_tensor_symbol_t a = ccv_nnc_tensor_symbol_new(symbolic_graph, ONE_CPU_TENSOR(1), "a");
18
1
  ccv_nnc_tensor_symbol_t b = ccv_nnc_tensor_symbol_new(symbolic_graph, ONE_CPU_TENSOR(1), "b");
19
1
  ccv_nnc_tensor_symbol_t c = ccv_nnc_tensor_symbol_new(symbolic_graph, ONE_CPU_TENSOR(1), "c");
20
1
  ccv_nnc_graph_exec_symbol_t prod = ccv_nnc_graph_exec_symbol_new(symbolic_graph, ccv_nnc_cmd(CCV_NNC_EWPROD_FORWARD, 0, 
CMD_GENERIC1
(), 0),
TENSOR_SYMBOL_LIST1
(a, b),
TENSOR_SYMBOL_LIST1
(c), "prod");
21
1
  ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS);
22
1
  ccv_nnc_graph_t* graph = 0;
23
1
  ccv_nnc_tensor_arena_t* tensor_arena = 0;
24
1
  ccv_nnc_graph_exec_arena_t* graph_exec_arena = 0;
25
1
  ccv_nnc_symbolic_graph_compile(symbolic_graph, 0, 0, 
GRAPH_EXEC_SYMBOL_LIST1
(prod),
GRAPH_EXEC_SYMBOL_LIST1
(prod), &graph, &tensor_arena, &graph_exec_arena);
26
1
  SYMBOLIC_GRAPH_GEN(symbolic_graph, CCV_NNC_SHORT_DOT_GRAPH);
27
1
  GRAPH_GEN(graph, CCV_NNC_SHORT_DOT_GRAPH);
28
1
  ccv_nnc_tensor_t* a_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, a);
29
1
  ccv_nnc_tensor_t* b_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b);
30
1
  ccv_nnc_tensor_t* c_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, c);
31
1
  a_tensor->data.f32[0] = 1.2;
32
1
  b_tensor->data.f32[0] = 2.3;
33
1
  ccv_nnc_graph_exec_t prod_exec = ccv_nnc_graph_exec_from_symbol(graph_exec_arena, prod);
34
1
  ccv_nnc_graph_run(graph, 0, 
GRAPH_EXEC_LIST1
(prod_exec),
GRAPH_EXEC_LIST1
(prod_exec));
35
1
  
REQUIRE1
(a_tensor->data.f32 == c_tensor->data.f32, "trivially in-place operation, should point to the same memory region")
;1
36
1
  
REQUIRE_EQ_WITH_TOLERANCE1
(c_tensor->data.f32[0], 1.2 * 2.3, 1e-6, "should be equal to 1.2 * 2.3")
;1
37
1
  ccv_nnc_graph_free(graph);
38
1
  ccv_nnc_tensor_arena_free(tensor_arena);
39
1
  ccv_nnc_graph_exec_arena_free(graph_exec_arena);
40
1
  ccv_nnc_symbolic_graph_free(symbolic_graph);
41
1
}
42
43
TEST_CASE("compile a simple symbolic graph with autogen")
44
1
{
45
1
  ccv_nnc_symbolic_graph_t* symbolic_graph = ccv_nnc_symbolic_graph_new();
46
1
  ccv_nnc_tensor_symbol_t a = ccv_nnc_tensor_symbol_new(symbolic_graph, ONE_CPU_TENSOR(31, 21, 2), "a");
47
1
  ccv_nnc_tensor_symbol_t b = ccv_nnc_tensor_symbol_new(symbolic_graph, ONE_CPU_TENSOR(31, 21, 4), "b");
48
1
  ccv_nnc_cmd_t forw_cmd = CMD_CONVOLUTION_FORWARD(4, 5, 3, 2);
49
1
  ccv_nnc_tensor_symbol_t w = ccv_nnc_tensor_symbol_new(symbolic_graph, ONE_CPU_TENSOR(4, 5, 3, 2), "w");
50
1
  ccv_nnc_tensor_symbol_t bias = ccv_nnc_tensor_symbol_new(symbolic_graph, ONE_CPU_TENSOR(4), "bias");
51
1
  // See what we compile to when have unused tensors.
52
1
  ccv_nnc_tensor_symbol_t unused0 = ccv_nnc_tensor_symbol_new(symbolic_graph, ONE_CPU_TENSOR(1), "unused0");
53
1
  ccv_nnc_tensor_symbol_t unused1 = ccv_nnc_tensor_symbol_new(symbolic_graph, ONE_CPU_TENSOR(1), "unused1");
54
1
  ccv_nnc_graph_exec_symbol_new(symbolic_graph, forw_cmd, 
TENSOR_SYMBOL_LIST1
(a, w, bias),
TENSOR_SYMBOL_LIST1
(b), "forw");
55
1
  ccv_nnc_tensor_symbol_t m = ccv_nnc_tensor_symbol_new(symbolic_graph, b.info, "m");
56
1
  ccv_nnc_cmd_t softmax_cmd = ccv_nnc_cmd(CCV_NNC_SOFTMAX_FORWARD, 0, ccv_nnc_cmd_auto, 0);
57
1
  ccv_nnc_graph_exec_symbol_new(symbolic_graph, softmax_cmd, 
TENSOR_SYMBOL_LIST1
(b),
TENSOR_SYMBOL_LIST1
(m), "softmax");
58
1
  ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS);
59
1
  ccv_nnc_graph_t* graph = 0;
60
1
  ccv_nnc_tensor_arena_t* tensor_arena = 0;
61
1
  ccv_nnc_graph_exec_arena_t* graph_exec_arena = 0;
62
1
  ccv_nnc_symbolic_graph_compile(symbolic_graph, 0, 0, ccv_nnc_symbolic_graph_sources(symbolic_graph), ccv_nnc_symbolic_graph_source_size(symbolic_graph), ccv_nnc_symbolic_graph_destinations(symbolic_graph), ccv_nnc_symbolic_graph_destination_size(symbolic_graph), &graph, &tensor_arena, &graph_exec_arena);
63
1
  SYMBOLIC_GRAPH_GEN(symbolic_graph, CCV_NNC_LONG_DOT_GRAPH);
64
1
  GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH);
65
1
  ccv_nnc_tensor_t* a_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, a);
66
1
  ccv_nnc_tensor_t* b_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b);
67
1
  ccv_nnc_tensor_t* m_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, m);
68
1
  
REQUIRE1
(a_tensor->data.u8 != b_tensor->data.u8, "tensor a and b shouldn't share the memory.")
;1
69
1
  
REQUIRE1
(b_tensor->data.u8 == m_tensor->data.u8, "tensor b and m should share the memory because softmax is an inplace op.")
;1
70
1
  
REQUIRE1
(ccv_nnc_tensor_from_symbol(tensor_arena, unused0) == 0, "tensor unused 0 should have not pointed memory.")
;1
71
1
  
REQUIRE1
(ccv_nnc_tensor_from_symbol(tensor_arena, unused1) == 0, "tensor unused 0 should have not pointed memory.")
;1
72
1
  ccv_nnc_symbolic_graph_free(symbolic_graph);
73
1
  ccv_nnc_graph_free(graph);
74
1
  ccv_nnc_tensor_arena_free(tensor_arena);
75
1
  ccv_nnc_graph_exec_arena_free(graph_exec_arena);
76
1
}
77
78
#include "case_main.h"