Line data Source code
1 : //------------------------------------------------------------------------------
2 : // LAGraph/experimental/test/test_dnn: test a small sparse deep neural network
3 : //------------------------------------------------------------------------------
4 :
5 : // LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved.
6 : // SPDX-License-Identifier: BSD-2-Clause
7 : //
8 : // For additional details (including references to third party source code and
9 : // other files) see the LICENSE file or contact permission@sei.cmu.edu. See
10 : // Contributors.txt for a full list of contributors. Created, in part, with
11 : // funding and support from the U.S. Government (see Acknowledgments.txt file).
12 : // DM22-0790
13 :
14 : // Contributed by Timothy A. Davis, Texas A&M University
15 :
16 : //------------------------------------------------------------------------------
17 :
18 : #include <stdio.h>
19 : #include <acutest.h>
20 : #include "LAGraphX.h"
21 : #include "LAGraph_test.h"
22 : #include "LG_Xtest.h"
23 : #include "LG_internal.h"
24 :
25 : char msg [LAGRAPH_MSG_LEN] ;
26 :
27 : //------------------------------------------------------------------------------
28 : // setup: start a test
29 : //------------------------------------------------------------------------------
30 :
31 1 : void setup (void)
32 : {
33 1 : OK (LAGraph_Init (msg)) ;
34 1 : OK (LAGraph_Random_Init (msg)) ;
35 1 : }
36 :
37 : //------------------------------------------------------------------------------
38 : // teardown: finalize a test
39 : //------------------------------------------------------------------------------
40 :
41 1 : void teardown (void)
42 : {
43 1 : OK (LAGraph_Random_Finalize (msg)) ;
44 1 : OK (LAGraph_Finalize (msg)) ;
45 1 : }
46 :
47 : //------------------------------------------------------------------------------
48 : // test_dnn: test a small DNN from https://graphchallenge.mit.edu/data-sets
49 : //------------------------------------------------------------------------------
50 :
51 : // This test uses the smallest sparse deep neural network at
52 : // https://graphchallenge.mit.edu/data-sets . The original problem has 120
53 : // layers, but the categories converge to the correct result in the first 27
54 : // layers, so only the first 32 layers are included in this test.
55 :
56 : // The original problem also hase 60,000 features (images) but in this
57 : // truncated problem, only the first 2000 features are used.
58 :
59 1 : void test_dnn (void)
60 : {
61 : GrB_Info info ;
62 1 : setup ( ) ;
63 :
64 : #define NLAYERS 30
65 : #define NLAYERS_ORIG 120
66 1 : int nlayers = NLAYERS ;
67 1 : float bias = -0.3 ;
68 1 : int nneurons = 1024 ;
69 1 : int nfeatures = 60000 ;
70 1 : int nfeatures_subset = 1200 ;
71 :
72 1 : printf ("\nSparse deep neural network from"
73 : " https://graphchallenge.mit.edu/data-sets\n"
74 : "# neurons: %d, bias: %g\n"
75 : "original # of layers: %d, layers used here: %d\n"
76 : "original # of features: %d, features used here: %d\n",
77 : nneurons, bias, NLAYERS_ORIG, nlayers, nfeatures, nfeatures_subset) ;
78 :
79 1 : GrB_Matrix Y0 = NULL, Y = NULL, W [NLAYERS], Bias [NLAYERS], T = NULL ;
80 1 : GrB_Vector TrueCategories = NULL, Categories = NULL, C = NULL ;
81 31 : for (int layer = 0 ; layer < nlayers ; layer++)
82 : {
83 30 : W [layer] = NULL ;
84 30 : Bias [layer] = NULL ;
85 : }
86 :
87 : #define LEN 512
88 : char filename [LEN] ;
89 :
90 : //--------------------------------------------------------------------------
91 : // read in the problem
92 : //--------------------------------------------------------------------------
93 :
94 1 : snprintf (filename, LEN, LG_DATA_DIR
95 : "/dnn_data/sparse-images-%d_subset.mtx", nneurons) ;
96 1 : FILE *f = fopen (filename, "r") ;
97 1 : TEST_CHECK (f != NULL) ;
98 1 : OK (LAGraph_MMRead (&Y0, f, msg)) ;
99 1 : fclose (f) ;
100 : char type_name [LAGRAPH_MAX_NAME_LEN] ;
101 1 : OK (LAGraph_Matrix_TypeName (type_name, Y0, msg)) ;
102 1 : TEST_CHECK (MATCHNAME (type_name, "float")) ;
103 1 : OK (GrB_wait (Y0, GrB_MATERIALIZE)) ;
104 :
105 31 : for (int layer = 0 ; layer < nlayers ; layer++)
106 : {
107 : // read the neuron layer: W [layer]
108 30 : snprintf (filename, LEN, LG_DATA_DIR "/dnn_data/n%d-l%d.mtx",
109 : nneurons, layer+1) ;
110 30 : f = fopen (filename, "r") ;
111 30 : TEST_CHECK (f != NULL) ;
112 30 : OK (LAGraph_MMRead (&(W [layer]), f, msg)) ;
113 30 : fclose (f) ;
114 30 : OK (LAGraph_Matrix_TypeName (type_name, W [layer], msg)) ;
115 30 : TEST_CHECK (MATCHNAME (type_name, "float")) ;
116 :
117 : // construct the bias matrix: Bias [layer]. Note that all Bias
118 : // matrices are the same for all layers, and all diagonal
119 : // entries are also the same.
120 30 : OK (GrB_Matrix_new (&(Bias [layer]), GrB_FP32, nneurons, nneurons)) ;
121 30750 : for (int i = 0 ; i < nneurons ; i++)
122 : {
123 30720 : OK (GrB_Matrix_setElement (Bias [layer], bias, i, i)) ;
124 : }
125 30 : OK (GrB_wait (Bias [layer], GrB_MATERIALIZE)) ;
126 : }
127 :
128 : // read T as a boolean nfeatures_subset-by-1 matrix
129 1 : snprintf (filename, LEN, LG_DATA_DIR
130 : "/dnn_data/neuron%d-l%d-categories_subset.mtx",
131 : nneurons, NLAYERS_ORIG) ;
132 1 : f = fopen (filename, "r") ;
133 1 : TEST_CHECK (f != NULL) ;
134 1 : OK (LAGraph_MMRead (&T, f, msg)) ;
135 1 : OK (LAGraph_Matrix_TypeName (type_name, T, msg)) ;
136 1 : TEST_CHECK (MATCHNAME (type_name, "bool")) ;
137 : // TrueCategories = T, as a boolean nfeatures-by-1 vector
138 1 : printf ("\nTrue categories:\n") ;
139 1 : OK (GrB_Vector_new (&TrueCategories, GrB_BOOL, nfeatures_subset)) ;
140 1 : OK (GrB_Col_extract (TrueCategories, NULL, NULL, T, GrB_ALL,
141 : nfeatures_subset, 0, NULL)) ;
142 1 : OK (LAGraph_Vector_Print (TrueCategories, LAGraph_COMPLETE, stdout, msg)) ;
143 1 : GrB_free (&T) ;
144 :
145 : //--------------------------------------------------------------------------
146 : // solve the problem
147 : //--------------------------------------------------------------------------
148 :
149 1 : OK (LAGraph_dnn (&Y, W, Bias, nlayers, Y0)) ;
150 :
151 : //--------------------------------------------------------------------------
152 : // check the result
153 : //--------------------------------------------------------------------------
154 :
155 : // C = sum (Y)
156 1 : OK (GrB_Vector_new (&C, GrB_FP32, nfeatures_subset)) ;
157 1 : OK (GrB_reduce (C, NULL, NULL, GrB_PLUS_FP32, Y, NULL));
158 : // Categories = pattern of C
159 1 : OK (GrB_Vector_new (&Categories, GrB_BOOL, nfeatures_subset)) ;
160 1 : OK (GrB_apply (Categories, NULL, NULL, GrB_ONEB_BOOL, C, (bool) true,
161 : NULL)) ;
162 :
163 : // check if Categories and TrueCategories are the same
164 : bool isequal ;
165 1 : printf ("\nComputed categories:\n") ;
166 1 : OK (LAGraph_Vector_Print (Categories, LAGraph_COMPLETE, stdout, msg)) ;
167 1 : OK (LAGraph_Vector_IsEqual (&isequal, TrueCategories, Categories, NULL)) ;
168 1 : TEST_CHECK (isequal) ;
169 :
170 : //--------------------------------------------------------------------------
171 : // free everything and finish the test
172 : //--------------------------------------------------------------------------
173 :
174 1 : GrB_free (&TrueCategories) ;
175 1 : GrB_free (&Categories) ;
176 1 : GrB_free (&C) ;
177 1 : GrB_free (&Y) ;
178 1 : GrB_free (&Y0) ;
179 31 : for (int layer = 0 ; layer < nlayers ; layer++)
180 : {
181 30 : GrB_free (& (W [layer])) ;
182 30 : GrB_free (& (Bias [layer])) ;
183 : }
184 :
185 : //--------------------------------------------------------------------------
186 : // error tests
187 : //--------------------------------------------------------------------------
188 :
189 1 : int result = LAGraph_dnn (NULL, NULL, NULL, nlayers, NULL) ;
190 1 : TEST_CHECK (result == GrB_NULL_POINTER) ;
191 :
192 1 : teardown ( ) ;
193 1 : }
194 :
195 : //------------------------------------------------------------------------------
196 : // TEST_LIST: all tests to run
197 : //------------------------------------------------------------------------------
198 :
199 : TEST_LIST = {
200 : {"DNN", test_dnn},
201 : {NULL, NULL}
202 : } ;
|