Skip to content

Commit 539f39a

Browse files
WIP: try to fix time comparison, but could not find root cause
1 parent 3ea6a83 commit 539f39a

File tree

1 file changed

+83
-5
lines changed

1 file changed

+83
-5
lines changed

examples/plot_compare_time.py

Lines changed: 83 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,24 @@ def compute_obj(X, y, w, alpha, l1_ratio=1):
5050

5151
models = ["lasso", "enet"]
5252

53+
# Global warmup to ensure all libraries are JIT-compiled before any benchmarking
54+
print("Performing global warmup to trigger JIT compilation...")
55+
for model_name in models:
56+
if model_name == "lasso":
57+
warmup_sklearn = Lasso_sklearn(alpha=alpha, fit_intercept=False, tol=1e-12)
58+
warmup_skglm = Lasso(alpha=alpha, fit_intercept=False, tol=1e-12)
59+
else: # enet
60+
warmup_sklearn = Enet_sklearn(
61+
alpha=alpha, fit_intercept=False, tol=1e-12, l1_ratio=0.5)
62+
warmup_skglm = ElasticNet(
63+
alpha=alpha, fit_intercept=False, tol=1e-12, l1_ratio=0.5)
64+
65+
print(f"Warming up {model_name} models...")
66+
# Use the full dataset for warmup to ensure all code paths are compiled
67+
_ = warmup_sklearn.fit(X, y)
68+
_ = warmup_skglm.fit(X, y)
69+
70+
# Now start the actual benchmarking
5371
fig, axarr = plt.subplots(2, 1, constrained_layout=True)
5472

5573
for ax, model, l1_ratio in zip(axarr, models, [1, 0.5]):
@@ -61,34 +79,94 @@ def compute_obj(X, y, w, alpha, l1_ratio=1):
6179
time_dict["sklearn"] = list()
6280
time_dict["us"] = list()
6381

64-
# Remove compilation time
82+
# Perform warmup runs with a small subset to trigger compilation
83+
_ = dict_sklearn[model].fit(X[:10], y[:10])
84+
_ = dict_ours[model].fit(X[:10], y[:10])
85+
86+
# Find optimal solution for reference
6587
dict_ours[model].max_iter = 10_000
6688
w_star = dict_ours[model].fit(X, y).coef_
6789
pobj_star = compute_obj(X, y, w_star, alpha, l1_ratio)
90+
91+
# Reset models with fresh instances after using them for reference solution
92+
if model == "lasso":
93+
dict_sklearn[model] = Lasso_sklearn(
94+
alpha=alpha, fit_intercept=False, tol=1e-12)
95+
dict_ours[model] = Lasso(
96+
alpha=alpha, fit_intercept=False, tol=1e-12)
97+
else: # enet
98+
dict_sklearn[model] = Enet_sklearn(
99+
alpha=alpha, fit_intercept=False, tol=1e-12, l1_ratio=0.5)
100+
dict_ours[model] = ElasticNet(
101+
alpha=alpha, fit_intercept=False, tol=1e-12, l1_ratio=0.5)
102+
103+
# # --------------------
104+
# # DEBUG: measure compile vs. solver iteration cost
105+
# debug_model = dict_ours[model]
106+
107+
# # 1) compile + first iteration
108+
# debug_model.max_iter = 1
109+
# t0 = time.time()
110+
# _ = debug_model.fit(X, y)
111+
# debug_total = time.time() - t0
112+
# print(f"[DEBUG] {model}: compile+1 iter = {debug_total:.3f}s")
113+
114+
# # 2) only solver iteration (post-compile)
115+
# debug_model.warm_start = True
116+
# debug_model.max_iter = 1
117+
# t0 = time.time()
118+
# _ = debug_model.fit(X, y)
119+
# debug_iter = time.time() - t0
120+
# print(f"[DEBUG] {model}: first iter post-compile = {debug_iter:.3f}s")
121+
122+
# # 3) iteration cost with fixpoint update
123+
# debug_model.warm_start = False
124+
# debug_model.ws_strategy = "fixpoint"
125+
# debug_model.max_iter = 1
126+
# t0 = time.time()
127+
# _ = debug_model.fit(X, y)
128+
# debug_fixpoint = time.time() - t0
129+
# print(f"[DEBUG] {model}: first iter fixpoint = {debug_fixpoint:.3f}s")
130+
# # --------------------
131+
132+
# warm up JIT so that no compile goes into your timing measurements
133+
print("warming up skglm on a little subset to pay the compile cost up‐front…")
134+
X_small, y_small = X[:10], y[:10]
135+
_ = Lasso(alpha=alpha, fit_intercept=False, tol=1e-12).fit(X_small, y_small)
136+
_ = ElasticNet(alpha=alpha, fit_intercept=False, tol=1e-12,
137+
l1_ratio=0.5).fit(X_small, y_small)
138+
139+
print("Warmup complete!")
140+
68141
for n_iter_sklearn in np.unique(np.geomspace(1, 50, num=15).astype(int)):
69142
dict_sklearn[model].max_iter = n_iter_sklearn
143+
print(f" sklearn iterations: {n_iter_sklearn}")
70144

71145
t_start = time.time()
72146
w_sklearn = dict_sklearn[model].fit(X, y).coef_
147+
73148
time_dict["sklearn"].append(time.time() - t_start)
74149
pobj_dict["sklearn"].append(compute_obj(X, y, w_sklearn, alpha, l1_ratio))
75150

76-
for n_iter_us in range(1, 10):
151+
for n_iter_us in np.unique(np.geomspace(1, 50, num=15).astype(int)):
77152
dict_ours[model].max_iter = n_iter_us
153+
print(f" skglm iterations: {n_iter_us}")
154+
78155
t_start = time.time()
79156
w = dict_ours[model].fit(X, y).coef_
157+
80158
time_dict["us"].append(time.time() - t_start)
81159
pobj_dict["us"].append(compute_obj(X, y, w, alpha, l1_ratio))
82160

83161
ax.semilogy(
84-
time_dict["sklearn"], pobj_dict["sklearn"] - pobj_star, label='sklearn')
162+
time_dict["sklearn"], pobj_dict["sklearn"] - pobj_star, marker='o', label='sklearn')
85163
ax.semilogy(
86-
time_dict["us"], pobj_dict["us"] - pobj_star, label='skglm')
164+
time_dict["us"], pobj_dict["us"] - pobj_star, marker='o', label='skglm')
87165

88166
ax.set_ylim((1e-10, 1))
89167
ax.set_title(model)
90168
ax.legend()
91169
ax.set_ylabel("Objective suboptimality")
92170

93171
axarr[1].set_xlabel("Time (s)")
94-
plt.show(block=False)
172+
plt.show()

0 commit comments

Comments
 (0)