Coverage Report

Created: 2017-11-12 13:27

/home/liu/buildslave/linux-x64-runtests/build/test/unit/nnc/while.backward.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 <nnc/_ccv_nnc_graph.h>
8
#include <3rdparty/dsfmt/dSFMT.h>
9
10
TEST_SETUP()
11
{
12
  ccv_nnc_init();
13
}
14
15
static int while_5(ccv_nnc_tensor_t* const* const commons, const int common_size, ccv_nnc_tensor_t* const* const inputs, const int input_size, ccv_nnc_tensor_t* const* const outputs, const int output_size, const void* const data)
16
12
{
17
12
  return commons[0]->data.i64[0] < 5;
18
12
}
19
20
TEST_CASE("graph with a while loop to compute back propagation 0.34 * 1.11 ^ 5")
21
1
{
22
1
  ccv_nnc_graph_t* graph = ccv_nnc_graph_new();
23
1
  ccv_nnc_tensor_t* y = ccv_nnc_tensor_new(0, ONE_CPU_TENSOR(1), 0);
24
1
  ccv_nnc_tensor_t* x0 = ccv_nnc_tensor_new(0, ONE_CPU_TENSOR(1), 0);
25
1
  ccv_nnc_tensor_t* x = ccv_nnc_tensor_new(0, ONE_CPU_TENSOR(1), 0);
26
1
  x->type |= CCV_TAPE_ALLOC;
27
1
  ccv_nnc_tensor_t* z = ccv_nnc_tensor_new(0, ONE_CPU_TENSOR(1), 0);
28
1
  z->type |= CCV_TAPE_ALLOC;
29
1
  ccv_nnc_tensor_t* g = ccv_nnc_tensor_new(0, ONE_CPU_TENSOR(1), 0);
30
1
  ccv_nnc_graph_t* while_graph = ccv_nnc_graph_new();
31
1
  ccv_nnc_graph_exec_t loop = ccv_nnc_graph_while(graph, CCV_NNC_GRAPH_FORWARD, while_graph);
32
1
  ccv_nnc_tensor_multiview_t xx;
33
1
  ccv_nnc_tensor_multiview((ccv_nnc_tensor_t*[]){
34
1
      x0, z, x
35
1
  }, CCV_NNC_MULTIVIEW_K1N, 2, while_graph, &xx);
36
1
  xx.type |= CCV_TAPE_ALLOC;
37
1
  ccv_nnc_tensor_multiview_t zz;
38
1
  ccv_nnc_tensor_multiview((ccv_nnc_tensor_t*[]){
39
1
      z, x
40
1
  }, CCV_NNC_MULTIVIEW_K0N, 2, while_graph, &zz);
41
1
  zz.type |= CCV_TAPE_ALLOC;
42
1
  ccv_nnc_graph_exec_t noop = ccv_nnc_graph_exec_new(while_graph, ccv_nnc_cmd(CCV_NNC_NOOP, 0, CMD_GENERIC(), 0), ccv_nnc_no_hint, 0, 0, 0, 0);
43
1
  ccv_nnc_graph_exec_t prod0 = ccv_nnc_graph_exec_new(while_graph, ccv_nnc_cmd(CCV_NNC_EWPROD_FORWARD, 0, 
CMD_GENERIC1
(), 0), ccv_nnc_no_hint,
TENSOR_LIST1
(y, (ccv_nnc_tensor_t*)&xx),
TENSOR_LIST1
((ccv_nnc_tensor_t*)&zz));
44
1
  ccv_nnc_graph_exec_concat(while_graph, noop, prod0);
45
1
  ccv_nnc_graph_set_sources(while_graph, GRAPH_EXEC_LIST(noop));
46
1
  ccv_nnc_graph_set_destinations(while_graph, GRAPH_EXEC_LIST(prod0));
47
1
  ccv_nnc_graph_set_while_expr(while_graph, while_5, 0, GRAPH_EXEC_LIST(noop));
48
1
  ccv_nnc_graph_t* while_back_graph = ccv_nnc_graph_new();
49
1
  while_back_graph->peer = while_graph;
50
1
  ccv_nnc_graph_exec_t back_loop = ccv_nnc_graph_while(graph, CCV_NNC_GRAPH_BACKWARD, while_back_graph);
51
1
  ccv_nnc_tensor_t* dx = ccv_nnc_tensor_new(0, ONE_CPU_TENSOR(1), 0);
52
1
  ccv_nnc_graph_exec_t back_prod0 = ccv_nnc_graph_exec_new(while_back_graph, ccv_nnc_cmd(CCV_NNC_EWPROD_BACKWARD, 0, 
CMD_GENERIC1
(), 0), ccv_nnc_no_hint,
TENSOR_LIST1
(g, y, (ccv_nnc_tensor_t*)&xx, (ccv_nnc_tensor_t*)&zz),
TENSOR_LIST1
(dx, g));
53
1
  ccv_nnc_graph_exec_t back_noop = ccv_nnc_graph_exec_new(while_back_graph, ccv_nnc_cmd(CCV_NNC_NOOP, 0, CMD_GENERIC(), 0), ccv_nnc_no_hint, 0, 0, 0, 0);
54
1
  ccv_nnc_graph_exec_concat(while_back_graph, back_prod0, back_noop);
55
1
  ccv_nnc_graph_set_sources(while_back_graph, GRAPH_EXEC_LIST(back_prod0));
56
1
  ccv_nnc_graph_set_destinations(while_back_graph, GRAPH_EXEC_LIST(back_noop));
57
1
  ccv_nnc_graph_set_while_expr(while_back_graph, while_5, 0, GRAPH_EXEC_LIST(back_noop));
58
1
  ccv_nnc_graph_exec_concat(graph, loop, back_loop);
59
1
  GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH);
60
1
  x0->data.f32[0] = 0.34;
61
1
  y->data.f32[0] = 1.11;
62
1
  g->data.f32[0] = 1;
63
1
  ccv_nnc_tensor_tape_t* tape = ccv_nnc_tensor_tape_new();
64
1
  ccv_nnc_graph_while_run(graph, tape, 0, 
GRAPH_EXEC_LIST1
(loop),
GRAPH_EXEC_LIST1
(back_loop));
65
1
  ccv_nnc_graph_free(graph);
66
1
  
REQUIRE_EQ_WITH_TOLERANCE1
(g->data.f32[0], 1.11 * 1.11 * 1.11 * 1.11 * 1.11, 1e-6, "back propagation of 0.34 * 1.11 ^ 5 should be 1.11 ^ 5")
;1
67
1
  ccv_nnc_tensor_tape_free(tape);
68
1
  ccv_nnc_tensor_multiview_free(xx);
69
1
  ccv_nnc_tensor_multiview_free(zz);
70
1
  ccv_nnc_tensor_free(x0);
71
1
  ccv_nnc_tensor_free(dx);
72
1
  ccv_nnc_tensor_free(x);
73
1
  ccv_nnc_tensor_free(y);
74
1
  ccv_nnc_tensor_free(z);
75
1
  ccv_nnc_tensor_free(g);
76
1
}
77
78
TEST_CASE("symbolic graph with a while loop z = log(x * y) (x <- z) 5 times, then u = v * z")
79
1
{
80
1
  ccv_nnc_symbolic_graph_t* symbolic_graph = ccv_nnc_symbolic_graph_new();
81
1
  ccv_nnc_tensor_symbol_t x = ccv_nnc_tensor_symbol_new(symbolic_graph, ONE_CPU_TENSOR(1), "x");
82
1
  ccv_nnc_tensor_symbol_t y = ccv_nnc_tensor_symbol_new(symbolic_graph, ONE_CPU_TENSOR(1), "y");
83
1
  ccv_nnc_symbolic_graph_t* while_graph = ccv_nnc_symbolic_graph_new();
84
1
  ccv_nnc_tensor_symbol_t xy = ccv_nnc_tensor_symbol_new(while_graph, ONE_CPU_TENSOR(1), "xy");
85
1
  ccv_nnc_tensor_symbol_t z = ccv_nnc_tensor_symbol_new(while_graph, ONE_CPU_TENSOR(1), "z");
86
1
  ccv_nnc_tensor_symbol_t u = ccv_nnc_tensor_symbol_new(symbolic_graph, ONE_CPU_TENSOR(1), "u");
87
1
  ccv_nnc_tensor_symbol_t v = ccv_nnc_tensor_symbol_new(symbolic_graph, ONE_CPU_TENSOR(1), "v");
88
1
  ccv_nnc_symbolic_graph_while(symbolic_graph, while_graph, "while0");
89
1
  ccv_nnc_graph_exec_symbol_t prod0 = ccv_nnc_graph_exec_symbol_new(while_graph, ccv_nnc_cmd(CCV_NNC_EWPROD_FORWARD, 0, 
CMD_GENERIC1
(), 0),
TENSOR_SYMBOL_LIST1
(x, y),
TENSOR_SYMBOL_LIST1
(xy), "prod0");
90
1
  ccv_nnc_graph_exec_symbol_t log0 = ccv_nnc_graph_exec_symbol_new(while_graph, ccv_nnc_cmd(CCV_NNC_EWLOG_FORWARD, 0, 
CMD_GENERIC1
(), 0),
TENSOR_SYMBOL_LIST1
(xy),
TENSOR_SYMBOL_LIST1
(z), "log0");
91
1
  ccv_nnc_graph_exec_symbol_autogen(while_graph, GRAPH_EXEC_SYMBOL_LIST(prod0, log0), 0);
92
1
  ccv_nnc_graph_exec_symbol_t noop = ccv_nnc_graph_exec_symbol_new(while_graph, ccv_nnc_cmd(CCV_NNC_NOOP, 0, CMD_GENERIC(), 0), 0, 0, 0, 0, "noop");
93
1
  ccv_nnc_graph_exec_symbol_concat(while_graph, noop, prod0);
94
1
  ccv_nnc_graph_exec_symbol_new(symbolic_graph, ccv_nnc_cmd(CCV_NNC_EWPROD_FORWARD, 0, 
CMD_GENERIC1
(), 0),
TENSOR_SYMBOL_LIST1
(z, v),
TENSOR_SYMBOL_LIST1
(u), "prod1");
95
1
  ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS);
96
1
  ccv_nnc_symbolic_graph_set_while_expr(while_graph, while_5, 0, GRAPH_EXEC_SYMBOL_LIST(noop));
97
1
  ccv_nnc_symbolic_graph_set_while_params(while_graph, TENSOR_SYMBOL_MAP(KV(z, x)));
98
1
  ccv_nnc_symbolic_graph_set_sources(while_graph, GRAPH_EXEC_SYMBOL_LIST(noop));
99
1
  ccv_nnc_symbolic_graph_set_destinations(while_graph, GRAPH_EXEC_SYMBOL_LIST(log0));
100
1
  ccv_nnc_graph_t* graph = 0;
101
1
  ccv_nnc_tensor_arena_t* tensor_arena = 0;
102
1
  ccv_nnc_graph_exec_arena_t* graph_exec_arena = 0;
103
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);
104
1
  GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH);
105
1
  ccv_nnc_tensor_t* x_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, x);
106
1
  ccv_nnc_tensor_t* y_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, y);
107
1
  ccv_nnc_tensor_t* v_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, v);
108
1
  x_tensor->data.f32[0] = 1;
109
1
  y_tensor->data.f32[0] = 3.2;
110
1
  v_tensor->data.f32[0] = 0.22;
111
1
  ccv_nnc_graph_exec_t source = ccv_nnc_graph_exec_source(graph_exec_arena);
112
1
  ccv_nnc_graph_exec_t destination = ccv_nnc_graph_exec_destination(graph_exec_arena);
113
1
  ccv_nnc_graph_while_run(graph, 0, 0, &source, 1, &destination, 1);
114
1
  ccv_nnc_tensor_t* u_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, u);
115
1
  float z0 = 1, y0 = 3.2;
116
1
  int i;
117
6
  for (i = 0; 
i < 56
;
i++5
)
118
5
    z0 = log(z0 * y0);
119
1
  z0 = 0.22 * z0;
120
1
  
REQUIRE_EQ_WITH_TOLERANCE1
(u_tensor->data.f32[0], z0, 1e-6, "u should match the for loop result")
;1
121
1
  ccv_nnc_graph_exec_arena_free(graph_exec_arena);
122
1
  ccv_nnc_tensor_arena_free(tensor_arena);
123
1
  ccv_nnc_graph_free(graph);
124
1
  ccv_nnc_symbolic_graph_backward(symbolic_graph, 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), 
TENSOR_SYMBOL_LIST1
(u),
TENSOR_SYMBOL_LIST1
(y));
125
1
  SYMBOLIC_GRAPH_GEN(symbolic_graph, CCV_NNC_LONG_DOT_GRAPH);
126
1
  ccv_nnc_symbolic_graph_free(symbolic_graph);
127
1
}
128
129
#include "case_main.h"