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 : }
35 :
36 : //------------------------------------------------------------------------------
37 : // teardown: finalize a test
38 : //------------------------------------------------------------------------------
39 :
40 1 : void teardown (void)
41 : {
42 1 : OK (LAGraph_Finalize (msg)) ;
43 1 : }
44 :
45 : //------------------------------------------------------------------------------
46 : // test_dnn: test a small DNN from https://graphchallenge.mit.edu/data-sets
47 : //------------------------------------------------------------------------------
48 :
49 : // This test uses the smallest sparse deep neural network at
50 : // https://graphchallenge.mit.edu/data-sets . The original problem has 120
51 : // layers, but the categories converge to the correct result in the first 27
52 : // layers, so only the first 32 layers are included in this test.
53 :
54 : // The original problem also hase 60,000 features (images) but in this
55 : // truncated problem, only the first 2000 features are used.
56 :
57 1 : void test_dnn (void)
58 : {
59 : GrB_Info info ;
60 1 : setup ( ) ;
61 :
62 : #define NLAYERS 30
63 : #define NLAYERS_ORIG 120
64 1 : int nlayers = NLAYERS ;
65 1 : float bias = -0.3 ;
66 1 : int nneurons = 1024 ;
67 1 : int nfeatures = 60000 ;
68 1 : int nfeatures_subset = 1200 ;
69 :
70 1 : printf ("\nSparse deep neural network from"
71 : " https://graphchallenge.mit.edu/data-sets\n"
72 : "# neurons: %d, bias: %g\n"
73 : "original # of layers: %d, layers used here: %d\n"
74 : "original # of features: %d, features used here: %d\n",
75 : nneurons, bias, NLAYERS_ORIG, nlayers, nfeatures, nfeatures_subset) ;
76 :
77 1 : GrB_Matrix Y0 = NULL, Y = NULL, W [NLAYERS], Bias [NLAYERS], T = NULL ;
78 1 : GrB_Vector TrueCategories = NULL, Categories = NULL, C = NULL ;
79 31 : for (int layer = 0 ; layer < nlayers ; layer++)
80 : {
81 30 : W [layer] = NULL ;
82 30 : Bias [layer] = NULL ;
83 : }
84 :
85 : #define LEN 512
86 : char filename [LEN] ;
87 :
88 : //--------------------------------------------------------------------------
89 : // read in the problem
90 : //--------------------------------------------------------------------------
91 :
92 1 : snprintf (filename, LEN, LG_DATA_DIR
93 : "/dnn_data/sparse-images-%d_subset.mtx", nneurons) ;
94 1 : FILE *f = fopen (filename, "r") ;
95 1 : TEST_CHECK (f != NULL) ;
96 1 : OK (LAGraph_MMRead (&Y0, f, msg)) ;
97 1 : fclose (f) ;
98 : char type_name [LAGRAPH_MAX_NAME_LEN] ;
99 1 : OK (LAGraph_Matrix_TypeName (type_name, Y0, msg)) ;
100 1 : TEST_CHECK (MATCHNAME (type_name, "float")) ;
101 1 : OK (GrB_wait (Y0, GrB_MATERIALIZE)) ;
102 :
103 31 : for (int layer = 0 ; layer < nlayers ; layer++)
104 : {
105 : // read the neuron layer: W [layer]
106 30 : snprintf (filename, LEN, LG_DATA_DIR "/dnn_data/n%d-l%d.mtx",
107 : nneurons, layer+1) ;
108 30 : f = fopen (filename, "r") ;
109 30 : TEST_CHECK (f != NULL) ;
110 30 : OK (LAGraph_MMRead (&(W [layer]), f, msg)) ;
111 30 : fclose (f) ;
112 30 : OK (LAGraph_Matrix_TypeName (type_name, W [layer], msg)) ;
113 30 : TEST_CHECK (MATCHNAME (type_name, "float")) ;
114 :
115 : // construct the bias matrix: Bias [layer]. Note that all Bias
116 : // matrices are the same for all layers, and all diagonal
117 : // entries are also the same.
118 30 : OK (GrB_Matrix_new (&(Bias [layer]), GrB_FP32, nneurons, nneurons)) ;
119 30750 : for (int i = 0 ; i < nneurons ; i++)
120 : {
121 30720 : OK (GrB_Matrix_setElement (Bias [layer], bias, i, i)) ;
122 : }
123 30 : OK (GrB_wait (Bias [layer], GrB_MATERIALIZE)) ;
124 : }
125 :
126 : // read T as a boolean nfeatures_subset-by-1 matrix
127 1 : snprintf (filename, LEN, LG_DATA_DIR
128 : "/dnn_data/neuron%d-l%d-categories_subset.mtx",
129 : nneurons, NLAYERS_ORIG) ;
130 1 : f = fopen (filename, "r") ;
131 1 : TEST_CHECK (f != NULL) ;
132 1 : OK (LAGraph_MMRead (&T, f, msg)) ;
133 1 : fclose (f) ;
134 1 : OK (LAGraph_Matrix_TypeName (type_name, T, msg)) ;
135 1 : TEST_CHECK (MATCHNAME (type_name, "bool")) ;
136 : // TrueCategories = T, as a boolean nfeatures-by-1 vector
137 1 : printf ("\nTrue categories:\n") ;
138 1 : OK (GrB_Vector_new (&TrueCategories, GrB_BOOL, nfeatures_subset)) ;
139 1 : OK (GrB_Col_extract (TrueCategories, NULL, NULL, T, GrB_ALL,
140 : nfeatures_subset, 0, NULL)) ;
141 1 : OK (LAGraph_Vector_Print (TrueCategories, LAGraph_COMPLETE, stdout, msg)) ;
142 1 : GrB_free (&T) ;
143 :
144 : //--------------------------------------------------------------------------
145 : // solve the problem
146 : //--------------------------------------------------------------------------
147 :
148 1 : OK (LAGraph_dnn (&Y, W, Bias, nlayers, Y0)) ;
149 :
150 : //--------------------------------------------------------------------------
151 : // check the result
152 : //--------------------------------------------------------------------------
153 :
154 : // C = sum (Y)
155 1 : OK (GrB_Vector_new (&C, GrB_FP32, nfeatures_subset)) ;
156 1 : OK (GrB_reduce (C, NULL, NULL, GrB_PLUS_FP32, Y, NULL));
157 : // Categories = pattern of C
158 1 : OK (GrB_Vector_new (&Categories, GrB_BOOL, nfeatures_subset)) ;
159 1 : OK (GrB_apply (Categories, NULL, NULL, GrB_ONEB_BOOL, C, (bool) true,
160 : NULL)) ;
161 :
162 : // check if Categories and TrueCategories are the same
163 : bool isequal ;
164 1 : printf ("\nComputed categories:\n") ;
165 1 : OK (LAGraph_Vector_Print (Categories, LAGraph_COMPLETE, stdout, msg)) ;
166 1 : OK (LAGraph_Vector_IsEqual (&isequal, TrueCategories, Categories, NULL)) ;
167 1 : TEST_CHECK (isequal) ;
168 :
169 : //--------------------------------------------------------------------------
170 : // free everything and finish the test
171 : //--------------------------------------------------------------------------
172 :
173 1 : GrB_free (&TrueCategories) ;
174 1 : GrB_free (&Categories) ;
175 1 : GrB_free (&C) ;
176 1 : GrB_free (&Y) ;
177 1 : GrB_free (&Y0) ;
178 31 : for (int layer = 0 ; layer < nlayers ; layer++)
179 : {
180 30 : GrB_free (& (W [layer])) ;
181 30 : GrB_free (& (Bias [layer])) ;
182 : }
183 :
184 : //--------------------------------------------------------------------------
185 : // error tests
186 : //--------------------------------------------------------------------------
187 :
188 1 : int result = LAGraph_dnn (NULL, NULL, NULL, nlayers, NULL) ;
189 1 : TEST_CHECK (result == GrB_NULL_POINTER) ;
190 :
191 1 : teardown ( ) ;
192 1 : }
193 :
194 : //------------------------------------------------------------------------------
195 : // TEST_LIST: all tests to run
196 : //------------------------------------------------------------------------------
197 :
198 : TEST_LIST = {
199 : {"DNN", test_dnn},
200 : {NULL, NULL}
201 : } ;
|