1 #include "cado.h" // IWYU pragma: keep
2
3 #include <list>
4 #include <map>
5 #include <string>
6 // #include <iostream>
7 #include <sstream>
8 #include <cstring> // strlcpy (openbsd) // IWYU pragma: keep
9
10 #include "las-descent-trees.hpp"
11 #include "portability.h"
12 #include "macros.h"
13
14
15 using namespace std;
16
display_tree(FILE * o,tree * t,string const & prefix)17 int descent_tree::display_tree(FILE* o, tree * t, string const& prefix) {
18 int res = 1;
19 char comment[10] = {'\0'};
20 if (!t->contender) {
21 if (t->try_again) {
22 snprintf(comment, sizeof(comment), " try%d", t->try_again);
23 } else {
24 size_t rc = strlcpy(comment, " ###", sizeof(comment));
25 ASSERT_ALWAYS(rc < sizeof(comment));
26 }
27 }
28 fprintf(o, "%s%s [%1.4f]%s\t\t%s\n",
29 prefix.c_str(), t->label().c_str(), t->spent,
30 comment,
31 t->label.fullname().c_str());
32 string new_prefix = prefix + " ";
33 typedef list<tree *>::iterator it_t;
34 for(it_t i = t->children.begin() ; i != t->children.end() ; i++) {
35 if (!display_tree(o, *i, new_prefix))
36 res = 0;
37 }
38 if (!t->contender)
39 res = 0;
40 return res;
41 }
42
display_last_tree(FILE * o)43 void descent_tree::display_last_tree(FILE * o) {
44 bool xs = is_successful(forest.back());
45 display_tree(o, forest.back(), xs ? "# ": "# FAILED ");
46 }
47
48 struct collected_stats {
49 bool ok;
50 double t;
51 int d;
52 int w;
collected_statscollected_stats53 collected_stats(bool ok, double t, int d, int w) :
54 ok(ok), t(t), d(d), w(w) {}
55 };
56
display_all_trees(FILE * o)57 void descent_tree::display_all_trees(FILE * o)
58 {
59 typedef list<tree *>::iterator it_t;
60 int total = 0, good = 0;
61 for(it_t i = forest.begin() ; i != forest.end() ; i++, total++) {
62 bool xs = is_successful(*i);
63 good += display_tree(o, *i, xs ? "# ": "# FAILED ");
64 }
65 fprintf(o, "# Success %d/%d (%1.2f%%)\n", good, total,
66 100.0 * (double) good / total);
67 list<collected_stats> foo;
68 typedef map<tree_label, list<collected_stats> > stats_t;
69 stats_t stats;
70 typedef stats_t::iterator sit_t;
71 for(it_t i = forest.begin() ; i != forest.end() ; i++, total++) {
72 collected_stats w(is_successful(*i),
73 (*i)->spent,
74 tree_depth(*i),
75 tree_weight(*i)
76 );
77 sit_t it = stats.find((*i)->label);
78 if (it == stats.end()) {
79 list<collected_stats> v;
80 v.push_back(w);
81 stats.insert(make_pair((*i)->label, v));
82 } else {
83 it->second.push_back(w);
84 }
85 }
86 #if 0
87 /* (since we've dropped the dependence on siever_config, we now
88 * longer do this)
89 */
90 /* We also use this to provide an updated stats file (whose
91 * results are based on actual descents, and thus less
92 * speculative) */
93
94 list<string> new_hints;
95 for(sit_t it = stats.begin() ; it != stats.end() ; it++) {
96 /* Collect and print stats for this sq size */
97 fprintf(o, "# Stats for %s\n", it->first().c_str());
98 int n = it->second.size();
99 int nok = 0;
100 double t1 = 0;
101 double t2 = 0;
102 double tmin = 999999;
103 double tmax = 0;
104 int d1 = 0;
105 int dmin = 0;
106 int dmax = 0;
107 int w1 = 0;
108 int wmin = 0;
109 int wmax = 0;
110 typedef list<collected_stats>::iterator lit_t;
111 for(lit_t i = it->second.begin() ; i != it->second.end() ; i++) {
112 nok += i->ok;
113 t1 += i->t;
114 t2 += i->t * i->t;
115 d1 += i->d;
116 w1 += i->w;
117 tmin = min(tmin, i->t);
118 tmax = max(tmax, i->t);
119 dmin = min(dmin, i->d);
120 dmax = max(dmax, i->d);
121 wmin = min(wmin, i->w);
122 wmax = max(wmax, i->w);
123 }
124 fprintf(o, "# success %.2f (%d/%d)\n", (double) nok / n, nok, n);
125 fprintf(o, "# depth avg %.1f, min %d, max %d\n",
126 (double) d1/n, dmin, dmax);
127 fprintf(o, "# weight avg %.1f, min %d, max %d\n",
128 (double) w1/n, wmin, wmax);
129 double tt1 = (double) t1/n;
130 double tt2 = (double) t2/n;
131 fprintf(o, "# time avg %.3f, sdev %.3f, min %.3f, max %.3f\n",
132 tt1, sqrt(tt2-tt1*tt1), tmin, tmax);
133
134 ostringstream os;
135 os << it->first()
136 << " " << tt1
137 << " " << (double) nok / n
138 << " I=" << it->first.sc->logI;
139 for(int i = 0 ; i < 2 ; i++) {
140 os << " " << it->first.sc->sides[i]->lim
141 << "," << it->first.sc->sides[i]->lpb
142 << "," << it->first.sc->sides[i]->mfb
143 << "," << it->first.sc->sides[i]->lambda;
144 }
145 new_hints.push_back(os.str());
146 }
147 fprintf(o, "# The following data is an _example_ which can be used to provide a hint file\n");
148 for(list<string>::iterator i = new_hints.begin() ; i != new_hints.end() ; i++) {
149 fprintf(o, "# %s\n", i->c_str());
150 }
151 #endif
152 }
153
154