dsh-eval-guard 0.6.1 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,88 @@
1
+ // Neural-CPP public interface. Implement everything declared here.
2
+ #pragma once
3
+
4
+ #include <cstddef>
5
+ #include <cstdint>
6
+ #include <memory>
7
+ #include <string>
8
+ #include <vector>
9
+
10
+ namespace nn {
11
+
12
+ using Shape = std::vector<int64_t>;
13
+
14
+ enum class DType : uint8_t {
15
+ F32, F64,
16
+ I8, I16, I32, I64, I128,
17
+ U8, U16, U32, U64, U128,
18
+ BF16, FP8_E5M2, MXFP4
19
+ };
20
+
21
+ enum class Rounding : uint8_t { NearestEven, TowardZero, Stochastic };
22
+ enum class ThreadMode : uint8_t { Development, Evaluation };
23
+
24
+ constexpr int kDevMaxThreads = 4;
25
+
26
+ std::size_t dtype_size(DType dtype);
27
+ const char* dtype_name(DType dtype);
28
+
29
+ class Tensor {
30
+ public:
31
+ Tensor();
32
+ Tensor(const Tensor&) = default;
33
+ Tensor(Tensor&&) noexcept = default;
34
+ Tensor& operator=(const Tensor&) = default;
35
+ Tensor& operator=(Tensor&&) noexcept = default;
36
+ ~Tensor();
37
+
38
+ static Tensor empty(const Shape& shape, DType dtype);
39
+ static Tensor from_data(const void* data, const Shape& shape, DType dtype);
40
+
41
+ const Shape& shape() const;
42
+ DType dtype() const;
43
+ int64_t ndim() const;
44
+ int64_t numel() const;
45
+ bool is_contiguous() const;
46
+
47
+ const void* data() const;
48
+ void* data();
49
+
50
+ Tensor to(DType dst, Rounding mode = Rounding::NearestEven, uint64_t seed = 0) const;
51
+ Tensor view(const Shape& shape) const;
52
+ Tensor reshape(const Shape& shape) const;
53
+ Tensor permute(const std::vector<int>& dims) const;
54
+ Tensor slice(int dim, int64_t start, int64_t stop, int64_t step = 1) const;
55
+ Tensor contiguous() const;
56
+ Tensor clone() const;
57
+
58
+ void set_requires_grad(bool value);
59
+ bool requires_grad() const;
60
+ Tensor grad() const;
61
+ void backward();
62
+
63
+ // Implementation detail. Exposed so the library implementer can define
64
+ // free functions without the header becoming a barrier.
65
+ struct Impl;
66
+ std::shared_ptr<Impl> impl_;
67
+ };
68
+
69
+ Tensor add(const Tensor& a, const Tensor& b);
70
+ Tensor sub(const Tensor& a, const Tensor& b);
71
+ Tensor mul(const Tensor& a, const Tensor& b);
72
+ Tensor div(const Tensor& a, const Tensor& b);
73
+ Tensor sum(const Tensor& a, int dim = -1);
74
+ Tensor mean(const Tensor& a, int dim = -1);
75
+
76
+ Tensor matmul(const Tensor& a, const Tensor& b);
77
+ Tensor matmul_nd(const Tensor& a, const Tensor& b,
78
+ const std::vector<int>& a_batch_dims,
79
+ const std::vector<int>& b_batch_dims,
80
+ const std::vector<int>& a_matrix_dims,
81
+ const std::vector<int>& b_matrix_dims);
82
+
83
+ void set_thread_mode(ThreadMode mode);
84
+ void set_num_threads(int n);
85
+ int num_threads();
86
+ int active_workers();
87
+
88
+ } // namespace nn
@@ -0,0 +1,126 @@
1
+ #include <algorithm>
2
+ #include <array>
3
+ #include <cmath>
4
+ #include <cstdio>
5
+ #include <cstring>
6
+ #include <iostream>
7
+ #include <random>
8
+ #include <sstream>
9
+ #include <string>
10
+ #include <vector>
11
+
12
+ namespace {
13
+ constexpr int N = 3;
14
+ constexpr double DT = 0.01;
15
+ constexpr int SUB = 4;
16
+ constexpr int MAX_STEPS = 3000;
17
+ constexpr double PI = 3.14159265358979323846;
18
+ constexpr double GRAV = 9.81;
19
+ constexpr double DAMP = 0.01;
20
+ constexpr double TAU_MAX = 18.0;
21
+ const std::array<double, N> MASS{{1.0, 1.0, 1.0}};
22
+ const std::array<double, N> LEN{{0.5, 0.5, 0.5}};
23
+ const std::array<double, N> R{{0.25, 0.25, 0.25}};
24
+ const std::array<double, N> INERTIA{{MASS[0]*LEN[0]*LEN[0]/12.0, MASS[1]*LEN[1]*LEN[1]/12.0, MASS[2]*LEN[2]*LEN[2]/12.0}};
25
+ const std::array<double, N> GCOEF{{MASS[0]*R[0] + LEN[0]*(MASS[1]+MASS[2]),
26
+ MASS[1]*R[1] + LEN[1]*MASS[2],
27
+ MASS[2]*R[2]}};
28
+
29
+ struct Vec { std::array<double,N> v{}; };
30
+ struct State { std::array<double,N> theta{}; std::array<double,N> omega{}; };
31
+
32
+ double wrap(double x) {
33
+ while (x <= -PI) x += 2*PI;
34
+ while (x > PI) x -= 2*PI;
35
+ return x;
36
+ }
37
+
38
+ static std::array<std::array<double,N>,N> mass_matrix(const std::array<double,N>& q) {
39
+ std::array<std::array<double,N>,N> M{};
40
+ for (int i=0;i<N;i++) for (int j=0;j<N;j++) {
41
+ if (i==j) {
42
+ double tail=0; for (int k=i+1;k<N;k++) tail += MASS[k];
43
+ M[i][j] = INERTIA[i] + MASS[i]*R[i]*R[i] + LEN[i]*LEN[i]*tail;
44
+ } else {
45
+ int a=std::min(i,j), b=std::max(i,j);
46
+ M[i][j] = LEN[a] * GCOEF[b] * std::cos(q[i]-q[j]);
47
+ }
48
+ }
49
+ return M;
50
+ }
51
+ static void solve3(const std::array<std::array<double,N>,N>& A, const std::array<double,N>& b, std::array<double,N>& x) {
52
+ double a[3][4];
53
+ for(int i=0;i<3;i++){ for(int j=0;j<3;j++) a[i][j]=A[i][j]; a[i][3]=b[i]; }
54
+ for(int c=0;c<3;c++){
55
+ int p=c; for(int r=c+1;r<3;r++) if(std::fabs(a[r][c])>std::fabs(a[p][c])) p=r;
56
+ if(p!=c) for(int j=0;j<4;j++) std::swap(a[c][j],a[p][j]);
57
+ double d=a[c][c]; if(std::fabs(d)<1e-15) d=(d<0?-1e-15:1e-15);
58
+ for(int j=c;j<4;j++) a[c][j]/=d;
59
+ for(int r=0;r<3;r++) if(r!=c){ double f=a[r][c]; for(int j=c;j<4;j++) a[r][j]-=f*a[c][j]; }
60
+ }
61
+ for(int i=0;i<3;i++) x[i]=a[i][3];
62
+ }
63
+ static void deriv(const State& s, const std::array<double,N>& tau, State& out) {
64
+ auto M = mass_matrix(s.theta);
65
+ std::array<double,N> C{}, G{}, Q{}, rhs{};
66
+ for(int i=0;i<N;i++){
67
+ double ci=0;
68
+ for(int j=0;j<N;j++) if(j!=i) ci += M[i][j] * std::sin(s.theta[i]-s.theta[j]) * s.omega[j]*s.omega[j];
69
+ C[i]=ci;
70
+ G[i]=GRAV*std::sin(s.theta[i])*GCOEF[i];
71
+ }
72
+ // joint damping: b * D^T D omega, D lower bidiagonal with -1 previous
73
+ for(int i=0;i<N;i++){
74
+ double e=s.omega[i] - (i>0?s.omega[i-1]:0.0);
75
+ Q[i] -= DAMP*e;
76
+ }
77
+ for(int i=0;i<N;i++) rhs[i]=tau[i]-C[i]-G[i]+Q[i];
78
+ solve3(M, rhs, out.omega);
79
+ out.theta = s.omega;
80
+ }
81
+ } // namespace
82
+
83
+ int main(int argc, char** argv) {
84
+ bool eval=false; int seed=0;
85
+ for(int i=1;i<argc;i++){ std::string a=argv[i]; if(a=="--eval") eval=true; else if(a=="--seed" && i+1<argc) seed=std::atoi(argv[++i]); }
86
+ std::mt19937 rng(seed);
87
+ std::uniform_real_distribution<double> u(-1.0,1.0);
88
+ State s;
89
+ int steps=0; bool ready=false;
90
+ auto reset=[&](){ steps=0; ready=true; if(eval){ s.theta={0.013,-0.008,0.021}; s.omega={0,0,0}; } else { s.theta={u(rng)*0.05,u(rng)*0.05,u(rng)*0.05}; s.omega={u(rng)*0.02,u(rng)*0.02,u(rng)*0.02}; } };
91
+ // zero state
92
+ s.theta={0,0,0}; s.omega={0,0,0};
93
+ std::string line;
94
+ while(std::getline(std::cin,line)){
95
+ if(line.empty()) continue;
96
+ if(line.find("reset")!=std::string::npos){ reset(); std::cout << "{\"obs\":[" << wrap(s.theta[0]-PI) << "," << wrap(s.theta[1]-PI) << "," << wrap(s.theta[2]-PI) << "]}\n" << std::flush; continue; }
97
+ if(line.find("step")!=std::string::npos){
98
+ if(!ready || steps>=MAX_STEPS){ std::cout << "{\"error\":\"episode_finished\"}\n" << std::flush; continue; }
99
+ // parse torque array
100
+ double u1=0,u3=0; auto p=line.find('['); if(p!=std::string::npos){ char* end=nullptr; u1=std::strtod(line.c_str()+p+1,&end); if(end){ const char* q=end; while(*q && (*q==','||*q==' ')) q++; u3=std::strtod(q,&end); } }
101
+ u1=std::max(-1.0,std::min(1.0,u1)); u3=std::max(-1.0,std::min(1.0,u3));
102
+ std::array<double,N> tau{{u1*TAU_MAX,0.0,u3*TAU_MAX}};
103
+ // one control step with 4 RK4 substeps
104
+ double h=DT/SUB;
105
+ for(int sub=0;sub<SUB;sub++){
106
+ State k1=s,k2=s,k3=s,k4=s; State d{};
107
+ deriv(k1,tau,d); for(int i=0;i<N;i++){ k2.theta[i]=s.theta[i]+0.5*h*d.theta[i]; k2.omega[i]=s.omega[i]+0.5*h*d.omega[i]; }
108
+ deriv(k2,tau,d); for(int i=0;i<N;i++){ k3.theta[i]=s.theta[i]+0.5*h*d.theta[i]; k3.omega[i]=s.omega[i]+0.5*h*d.omega[i]; }
109
+ deriv(k3,tau,d); for(int i=0;i<N;i++){ k4.theta[i]=s.theta[i]+h*d.theta[i]; k4.omega[i]=s.omega[i]+h*d.omega[i]; }
110
+ deriv(k4,tau,d);
111
+ // need derivatives at all; use helper recompute arrays
112
+ State ds1{},ds2{},ds3{},ds4{};
113
+ deriv(k1,tau,ds1); deriv(k2,tau,ds2); deriv(k3,tau,ds3); deriv(k4,tau,ds4);
114
+ for(int i=0;i<N;i++){
115
+ s.theta[i] += h/6.0*(ds1.theta[i]+2*ds2.theta[i]+2*ds3.theta[i]+ds4.theta[i]);
116
+ s.omega[i] += h/6.0*(ds1.omega[i]+2*ds2.omega[i]+2*ds3.omega[i]+ds4.omega[i]);
117
+ }
118
+ }
119
+ steps++;
120
+ std::cout << "{\"obs\":[" << wrap(s.theta[0]-PI) << "," << wrap(s.theta[1]-PI) << "," << wrap(s.theta[2]-PI) << "]}\n" << std::flush;
121
+ continue;
122
+ }
123
+ std::cout << "{\"error\":\"bad_command\"}\n" << std::flush;
124
+ }
125
+ return 0;
126
+ }
Binary file
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env python3
2
+ """Plugin wrapper for the standalone Neural-Pendulum evaluator."""
3
+ from __future__ import annotations
4
+ import os
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ HERE = Path(__file__).resolve().parent
9
+ STANDALONE = HERE.parent / 'neural-pendulum-eval' / 'run_eval.py'
10
+
11
+ if not STANDALONE.is_file():
12
+ print('neural-pendulum-eval/run_eval.py missing; copy the standalone evaluator folder first', file=sys.stderr)
13
+ raise SystemExit(1)
14
+
15
+ os.execv(sys.executable, [sys.executable, '-X', 'utf8', str(STANDALONE), *sys.argv[1:]])
@@ -94,7 +94,9 @@ window.__ModuleLoader__.load({
94
94
  pipProxyUrl: "",
95
95
  cifarProxyUrl: "",
96
96
  cifarMirror: "toronto",
97
- customCifarUrl: ""
97
+ customCifarUrl: "",
98
+ parallelEval: false,
99
+ taskId: ""
98
100
  };
99
101
  const box = {
100
102
  border: "1px solid var(--vscode-panel-border, #3c3c3c)",
@@ -159,7 +161,9 @@ window.__ModuleLoader__.load({
159
161
  pipProxyUrl: typeof value?.pipProxyUrl === "string" ? value.pipProxyUrl : "",
160
162
  cifarProxyUrl: typeof value?.cifarProxyUrl === "string" ? value.cifarProxyUrl : "",
161
163
  cifarMirror: typeof value?.cifarMirror === "string" && value.cifarMirror !== "" ? value.cifarMirror : "toronto",
162
- customCifarUrl: typeof value?.customCifarUrl === "string" ? value.customCifarUrl : ""
164
+ customCifarUrl: typeof value?.customCifarUrl === "string" ? value.customCifarUrl : "",
165
+ parallelEval: value?.parallelEval === true,
166
+ taskId: typeof value?.taskId === "string" ? value.taskId : ""
163
167
  };
164
168
  }
165
169
  /** The settings card. */
@@ -237,8 +241,15 @@ window.__ModuleLoader__.load({
237
241
  return () => clearInterval(timer);
238
242
  }, []);
239
243
  (0, react.useEffect)(() => {
240
- if (state !== null && state.tasks.length > 0 && (taskId === "" || !state.tasks.some((task) => task.id === taskId))) setTaskId(state.tasks[0].id);
241
- }, [state, taskId]);
244
+ if (state !== null && state.tasks.length > 0 && (taskId === "" || !state.tasks.some((task) => task.id === taskId))) {
245
+ if (draft.taskId !== "" && state.tasks.some((task) => task.id === draft.taskId)) setTaskId(draft.taskId);
246
+ else setTaskId(state.tasks[0].id);
247
+ }
248
+ }, [
249
+ state,
250
+ taskId,
251
+ draft.taskId
252
+ ]);
242
253
  const ready = snapshot.status === "ready" && snapshot.writable;
243
254
  const save = async (patch) => {
244
255
  if (!ready || snapshot.revision === void 0) return;
@@ -274,6 +285,7 @@ window.__ModuleLoader__.load({
274
285
  };
275
286
  const selectTask = (next) => {
276
287
  setTaskId(next);
288
+ save({ taskId: next });
277
289
  try {
278
290
  localStorage.setItem("evalGuard.taskId", next);
279
291
  } catch {}
@@ -332,6 +344,7 @@ window.__ModuleLoader__.load({
332
344
  };
333
345
  const install = async () => {
334
346
  if (workspaceId === "" || taskId === "") return;
347
+ await save({ taskId });
335
348
  setError("");
336
349
  setNotice("");
337
350
  setJobNotice("");
@@ -368,6 +381,7 @@ window.__ModuleLoader__.load({
368
381
  };
369
382
  const evaluate = async () => {
370
383
  if (workspaceId === "" || taskId === "") return;
384
+ await save({ taskId });
371
385
  setError("");
372
386
  setNotice("");
373
387
  setJobNotice("");
@@ -814,6 +828,23 @@ window.__ModuleLoader__.load({
814
828
  " ",
815
829
  t("settings.timeLimit")
816
830
  ] }),
831
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
832
+ style: { marginLeft: 16 },
833
+ children: [
834
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
835
+ type: "checkbox",
836
+ checked: draft.parallelEval,
837
+ disabled: !ready,
838
+ onChange: (event) => void save({ parallelEval: event.target.checked })
839
+ }),
840
+ " ",
841
+ t("settings.parallelEval")
842
+ ]
843
+ }),
844
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
845
+ style: note,
846
+ children: t("settings.parallelEvalHint")
847
+ }),
817
848
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
818
849
  type: "number",
819
850
  min: 1,
@@ -998,6 +1029,8 @@ window.__ModuleLoader__.load({
998
1029
  "settings.runningForce": "强行开启",
999
1030
  "settings.timeLimit": "开启最长时长",
1000
1031
  "settings.timeLimitHint": "从每条用户消息发送时开始计时;到点只终止当前轮次,并递归清理子代理与后台任务。",
1032
+ "settings.parallelEval": "多 agent 并行评测",
1033
+ "settings.parallelEvalHint": "启用后,安装任务时会在提示词中提醒 agent:运行环境可能因其他 agent 的行为而波动,需要自行适应。",
1001
1034
  "settings.minutes": "分钟",
1002
1035
  "settings.forbidden": "额外禁止路径",
1003
1036
  "settings.forbiddenHint": "每行一个绝对路径;# 开头为注释;! 开头表示在禁止范围内放开该子路径;按行顺序生效。默认空。",
@@ -1041,6 +1074,8 @@ window.__ModuleLoader__.load({
1041
1074
  "settings.recent": "最近事件",
1042
1075
  "settings.none": "暂无。",
1043
1076
  "settings.warningTitle": "评测守护警告",
1077
+ "settings.cifarProxy": "CIFAR 下载代理",
1078
+ "settings.cifarMirror": "CIFAR 下载镜像",
1044
1079
  "settings.close": "关闭"
1045
1080
  };
1046
1081
  const en = {
@@ -1053,6 +1088,8 @@ window.__ModuleLoader__.load({
1053
1088
  "settings.runningForce": "Force enable",
1054
1089
  "settings.timeLimit": "Enable time limit",
1055
1090
  "settings.timeLimitHint": "The clock starts at each user message; at the deadline only the current turn is cancelled, and subagents/jobs are cleaned up recursively.",
1091
+ "settings.parallelEval": "Parallel agent evaluation",
1092
+ "settings.parallelEvalHint": "When enabled, install prompts warn the agent that the runtime may fluctuate because other agents share the machine; it must adapt.",
1056
1093
  "settings.minutes": "minutes",
1057
1094
  "settings.forbidden": "Extra forbidden paths",
1058
1095
  "settings.forbiddenHint": "One absolute path per line; # comments; ! re-allows a subpath; later lines win. Empty by default.",