00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <tcl.h>
00022 #include <ctype.h>
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026
00027 #include "AtomSel.h"
00028 #include "Benchmark.h"
00029 #include "config.h"
00030 #include "VMDApp.h"
00031 #include "TclCommands.h"
00032 #include "CUDAKernels.h"
00033 #include "CUDAAccel.h"
00034 #include "WKFThreads.h"
00035
00036 static void cmd_vmdbench_usage(Tcl_Interp *interp) {
00037 Tcl_AppendResult(interp,
00038 "usage: vmdbench <command> [args...]\n"
00039 "vmdbench stream [N] - built-in STREAM memory bandwidth test\n",
00040 "vmdbench cudamadd [devices] - CUDA multiply-add arithmetic (*)\n",
00041 "vmdbench cudabusbw [devices] - CUDA host/device bus bandwidth (*)\n",
00042 "vmdbench cudaglobmembw [devices] - CUDA global memory bandwidth (*)\n",
00043 "vmdbench cudadevpool [N] - CUDA threadpool run-cycle latency (*)\n",
00044 "(*) Only available in CUDA-enabled builds of VMD\n",
00045 NULL);
00046 }
00047
00048 int text_cmd_vmdbench(ClientData cd, Tcl_Interp *interp, int argc,
00049 const char *argv[]) {
00050 #if defined(VMDCUDA)
00051 VMDApp *app = (VMDApp *)cd;
00052 #endif
00053
00054 if (argc == 1) {
00055 cmd_vmdbench_usage(interp);
00056 return TCL_ERROR;
00057 }
00058
00059 if (argc >= 2) {
00060 if (!strupncmp(argv[1], "stream", CMDLEN)) {
00061 double times[8], mbsec[8];
00062 int N = 1024*1024 * 16;
00063
00064 if (argc == 3) {
00065 if (Tcl_GetInt(interp, argv[2], &N) != TCL_OK) {
00066 Tcl_AppendResult(interp, " in vmdbench stream", NULL);
00067 return TCL_ERROR;
00068 }
00069 }
00070
00071 int rc = stream_bench(N, times, mbsec);
00072 if (rc) {
00073 Tcl_AppendResult(interp,
00074 "unable to complete stream benchmark, out of memory", NULL);
00075 return TCL_ERROR;
00076 }
00077
00078 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00079 const char *benchnames[] = {
00080 "copy (double)",
00081 "scale (double)",
00082 "add (double)",
00083 "triad (double)",
00084 "copy (float)",
00085 "scale (float)",
00086 "add (float)",
00087 "triad (float)"
00088 };
00089
00090 Tcl_Obj *colNameObj = Tcl_NewListObj(0, NULL);
00091 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Test", -1));
00092 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Time", -1));
00093 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("MB/sec", -1));
00094 Tcl_ListObjAppendElement(interp, tcl_result, colNameObj);
00095
00096 int i;
00097 for (i=0; i<8; i++) {
00098 Tcl_Obj *rowListObj = Tcl_NewListObj(0, NULL);
00099 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewStringObj(benchnames[i], -1));
00100 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(times[i]));
00101 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(mbsec[i]));
00102 Tcl_ListObjAppendElement(interp, tcl_result, rowListObj);
00103
00104 }
00105 Tcl_SetObjResult(interp, tcl_result);
00106
00107 return TCL_OK;
00108
00109 } else if (!strupncmp(argv[1], "minmaxmean_1fv", CMDLEN)) {
00110 double runtime, mbsec;
00111 int N = 1024*1024 * 16;
00112 int reps = 1;
00113
00114 if (argc >= 3) {
00115 if (Tcl_GetInt(interp, argv[2], &N) != TCL_OK) {
00116 Tcl_AppendResult(interp, " in vmdbench minmaxmean_1fv", NULL);
00117 return TCL_ERROR;
00118 }
00119 }
00120 if (argc == 4) {
00121 if (Tcl_GetInt(interp, argv[3], &reps) != TCL_OK) {
00122 Tcl_AppendResult(interp, " in vmdbench minmaxmean_1fv", NULL);
00123 return TCL_ERROR;
00124 }
00125 }
00126
00127 vmdbench_minmaxmean_1fv(N, reps, runtime, mbsec);
00128
00129 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00130 Tcl_Obj *colNameObj = Tcl_NewListObj(0, NULL);
00131 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Time", -1));
00132 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("MB/sec", -1));
00133 Tcl_ListObjAppendElement(interp, tcl_result, colNameObj);
00134
00135 Tcl_Obj *rowListObj = Tcl_NewListObj(0, NULL);
00136 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(runtime));
00137 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(mbsec));
00138
00139 Tcl_ListObjAppendElement(interp, tcl_result, rowListObj);
00140 Tcl_SetObjResult(interp, tcl_result);
00141
00142 return TCL_OK;
00143
00144 } else if (!strupncmp(argv[1], "minmax_3fv", CMDLEN)) {
00145 double runtime, mbsec;
00146 int N = 1024*1024 * 16;
00147 int reps = 1;
00148
00149 if (argc >= 3) {
00150 if (Tcl_GetInt(interp, argv[2], &N) != TCL_OK) {
00151 Tcl_AppendResult(interp, " in vmdbench minmax_3fv", NULL);
00152 return TCL_ERROR;
00153 }
00154 }
00155 if (argc == 4) {
00156 if (Tcl_GetInt(interp, argv[3], &reps) != TCL_OK) {
00157 Tcl_AppendResult(interp, " in vmdbench minmax_3fv", NULL);
00158 return TCL_ERROR;
00159 }
00160 }
00161
00162 vmdbench_minmax_3fv(N, reps, runtime, mbsec);
00163
00164 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00165 Tcl_Obj *colNameObj = Tcl_NewListObj(0, NULL);
00166 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Time", -1));
00167 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("MB/sec", -1));
00168 Tcl_ListObjAppendElement(interp, tcl_result, colNameObj);
00169
00170 Tcl_Obj *rowListObj = Tcl_NewListObj(0, NULL);
00171 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(runtime));
00172 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(mbsec));
00173
00174 Tcl_ListObjAppendElement(interp, tcl_result, rowListObj);
00175 Tcl_SetObjResult(interp, tcl_result);
00176
00177 return TCL_OK;
00178
00179 } else if (!strupncmp(argv[1], "analyze_selection", CMDLEN)) {
00180 double runtime, mbsec;
00181 int N = 1024*1024 * 16;
00182 int reps = 1;
00183
00184 if (argc >= 3) {
00185 if (Tcl_GetInt(interp, argv[2], &N) != TCL_OK) {
00186 Tcl_AppendResult(interp, " in vmdbench analyze_selection", NULL);
00187 return TCL_ERROR;
00188 }
00189 }
00190 if (argc == 4) {
00191 if (Tcl_GetInt(interp, argv[3], &reps) != TCL_OK) {
00192 Tcl_AppendResult(interp, " in vmdbench analyze_selection", NULL);
00193 return TCL_ERROR;
00194 }
00195 }
00196
00197 vmdbench_analyze_selection(N, reps, runtime, mbsec);
00198
00199 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00200 Tcl_Obj *colNameObj = Tcl_NewListObj(0, NULL);
00201 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Time", -1));
00202 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("MB/sec", -1));
00203 Tcl_ListObjAppendElement(interp, tcl_result, colNameObj);
00204
00205 Tcl_Obj *rowListObj = Tcl_NewListObj(0, NULL);
00206 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(runtime));
00207 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(mbsec));
00208
00209 Tcl_ListObjAppendElement(interp, tcl_result, rowListObj);
00210 Tcl_SetObjResult(interp, tcl_result);
00211
00212 return TCL_OK;
00213
00214 } else if (!strupncmp(argv[1], "cudamadd", CMDLEN)) {
00215 #if defined(VMDCUDA)
00216 int numdevs, physnumdevs;
00217 int *devlist = NULL;
00218 vmd_cuda_num_devices(&physnumdevs);
00219 numdevs = physnumdevs;
00220 #if !defined(VMDTHREADS)
00221 numdevs = 1;
00222 #endif
00223
00224
00225 if (argc > 2) {
00226 if ((argc-2) > numdevs) {
00227 Tcl_AppendResult(interp, "vmdbench: bad device argument", NULL);
00228 return TCL_ERROR;
00229 } else {
00230 numdevs = argc-2;
00231 }
00232 devlist = (int *) malloc(numdevs * sizeof(int));
00233 int arg, dev;
00234 for (arg=0; arg<numdevs; arg++) {
00235 if (Tcl_GetInt(interp, argv[arg+2], &dev) != TCL_OK) {
00236 Tcl_AppendResult(interp, "vmdbench: bad device argument", NULL);
00237 free(devlist);
00238 return TCL_ERROR;
00239 }
00240 if (dev < 0 || dev >= physnumdevs) {
00241 Tcl_AppendResult(interp, "vmdbench: device argument out of range", NULL);
00242 free(devlist);
00243 return TCL_ERROR;
00244 }
00245 devlist[arg] = dev;
00246 }
00247 }
00248
00249 double *gflops = (double *) malloc(numdevs * sizeof(double));
00250 int testloops=10;
00251 if (getenv("VMDMADDLOOPS") != NULL)
00252 testloops = atoi(getenv("VMDMADDLOOPS"));
00253
00254 vmd_cuda_madd_gflops(numdevs, devlist, gflops, testloops);
00255
00256 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00257 Tcl_Obj *colNameObj = Tcl_NewListObj(0, NULL);
00258 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Device", -1));
00259 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("GFLOPS", -1));
00260 Tcl_ListObjAppendElement(interp, tcl_result, colNameObj);
00261
00262 int i;
00263 for (i=0; i<numdevs; i++) {
00264 Tcl_Obj *rowListObj = Tcl_NewListObj(0, NULL);
00265 if (devlist != NULL)
00266 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewIntObj(devlist[i]));
00267 else
00268 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewIntObj(i));
00269 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(gflops[i]));
00270 Tcl_ListObjAppendElement(interp, tcl_result, rowListObj);
00271 }
00272 Tcl_SetObjResult(interp, tcl_result);
00273
00274 if (devlist)
00275 free(devlist);
00276
00277 return TCL_OK;
00278 #else
00279 Tcl_AppendResult(interp, "CUDA Acceleration not available in this build", NULL);
00280 return TCL_ERROR;
00281 #endif
00282 } else if (!strupncmp(argv[1], "cudabusbw", CMDLEN)) {
00283 #if defined(VMDCUDA)
00284 int numdevs, physnumdevs;
00285 int *devlist = NULL;
00286 vmd_cuda_num_devices(&physnumdevs);
00287 numdevs = physnumdevs;
00288 #if !defined(VMDTHREADS)
00289 numdevs = 1;
00290 #endif
00291
00292
00293 if (argc > 2) {
00294 if ((argc-2) > numdevs) {
00295 Tcl_AppendResult(interp, "vmdbench: bad device argument", NULL);
00296 return TCL_ERROR;
00297 } else {
00298 numdevs = argc-2;
00299 }
00300 devlist = (int *) malloc(numdevs * sizeof(int));
00301 int arg, dev;
00302 for (arg=0; arg<numdevs; arg++) {
00303 if (Tcl_GetInt(interp, argv[arg+2], &dev) != TCL_OK) {
00304 Tcl_AppendResult(interp, "vmdbench: bad device argument", NULL);
00305 free(devlist);
00306 return TCL_ERROR;
00307 }
00308 if (dev < 0 || dev >= physnumdevs) {
00309 Tcl_AppendResult(interp, "vmdbench: device argument out of range", NULL);
00310 free(devlist);
00311 return TCL_ERROR;
00312 }
00313 devlist[arg] = dev;
00314 }
00315 }
00316
00317 double *hdmbsec = (double *) malloc(numdevs * sizeof(double));
00318 double *hdlatusec = (double *) malloc(numdevs * sizeof(double));
00319 double *phdmbsec = (double *) malloc(numdevs * sizeof(double));
00320 double *phdlatusec = (double *) malloc(numdevs * sizeof(double));
00321 double *dhmbsec = (double *) malloc(numdevs * sizeof(double));
00322 double *dhlatusec = (double *) malloc(numdevs * sizeof(double));
00323 double *pdhmbsec = (double *) malloc(numdevs * sizeof(double));
00324 double *pdhlatusec = (double *) malloc(numdevs * sizeof(double));
00325
00326 vmd_cuda_bus_bw(numdevs, devlist,
00327 hdmbsec, hdlatusec, phdmbsec, phdlatusec,
00328 dhmbsec, dhlatusec, pdhmbsec, pdhlatusec);
00329
00330 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00331 Tcl_Obj *colNameObj = Tcl_NewListObj(0, NULL);
00332 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Device", -1));
00333 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Host-device bandwidth (MB/sec)", -1));
00334 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Host-device latency (usec)", -1));
00335 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Host-device pinned bandwidth (MB/sec)", -1));
00336 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Host-device pinned latency (usec)", -1));
00337 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Device-host bandwidth (MB/sec)", -1));
00338 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Device-host latency (usec)", -1));
00339 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Device-host pinned bandwidth (MB/sec)", -1));
00340 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Device-host pinned latency (usec)", -1));
00341 Tcl_ListObjAppendElement(interp, tcl_result, colNameObj);
00342
00343 int i;
00344 for (i=0; i<numdevs; i++) {
00345 Tcl_Obj *rowListObj = Tcl_NewListObj(0, NULL);
00346 if (devlist != NULL)
00347 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewIntObj(devlist[i]));
00348 else
00349 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewIntObj(i));
00350
00351 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(hdmbsec[i]));
00352 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(hdlatusec[i]));
00353 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(phdmbsec[i]));
00354 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(phdlatusec[i]));
00355 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(dhmbsec[i]));
00356 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(dhlatusec[i]));
00357 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(pdhmbsec[i]));
00358 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(pdhlatusec[i]));
00359 Tcl_ListObjAppendElement(interp, tcl_result, rowListObj);
00360 }
00361 Tcl_SetObjResult(interp, tcl_result);
00362 return TCL_OK;
00363 #else
00364 Tcl_AppendResult(interp, "CUDA Acceleration not available in this build", NULL);
00365 return TCL_ERROR;
00366 #endif
00367 } else if (!strupncmp(argv[1], "cudaglobmembw", CMDLEN)) {
00368 #if defined(VMDCUDA)
00369 int numdevs, physnumdevs;
00370 int *devlist = NULL;
00371 vmd_cuda_num_devices(&physnumdevs);
00372 numdevs = physnumdevs;
00373 #if !defined(VMDTHREADS)
00374 numdevs = 1;
00375 #endif
00376
00377
00378 if (argc > 2) {
00379 if ((argc-2) > numdevs) {
00380 Tcl_AppendResult(interp, "vmdbench: bad device argument", NULL);
00381 return TCL_ERROR;
00382 } else {
00383 numdevs = argc-2;
00384 }
00385 devlist = (int *) malloc(numdevs * sizeof(int));
00386 int arg, dev;
00387 for (arg=0; arg<numdevs; arg++) {
00388 if (Tcl_GetInt(interp, argv[arg+2], &dev) != TCL_OK) {
00389 Tcl_AppendResult(interp, "vmdbench: bad device argument", NULL);
00390 free(devlist);
00391 return TCL_ERROR;
00392 }
00393 if (dev < 0 || dev >= physnumdevs) {
00394 Tcl_AppendResult(interp, "vmdbench: device argument out of range", NULL);
00395 free(devlist);
00396 return TCL_ERROR;
00397 }
00398 devlist[arg] = dev;
00399 }
00400 }
00401
00402 double *memsetgbsec = (double *) malloc(numdevs * sizeof(double));
00403 double *memcpygbsec = (double *) malloc(numdevs * sizeof(double));
00404
00405 vmd_cuda_globmem_bw(numdevs, devlist, memsetgbsec, memcpygbsec);
00406
00407 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00408 Tcl_Obj *colNameObj = Tcl_NewListObj(0, NULL);
00409 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Device", -1));
00410 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Memory set bandwidth (GB/sec)", -1));
00411 Tcl_ListObjAppendElement(interp, colNameObj, Tcl_NewStringObj("Memory copy bandwidth (GB/sec)", -1));
00412 Tcl_ListObjAppendElement(interp, tcl_result, colNameObj);
00413
00414 int i;
00415 for (i=0; i<numdevs; i++) {
00416 Tcl_Obj *rowListObj = Tcl_NewListObj(0, NULL);
00417 if (devlist != NULL)
00418 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewIntObj(devlist[i]));
00419 else
00420 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewIntObj(i));
00421
00422 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(memsetgbsec[i]));
00423 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(memcpygbsec[i]));
00424 Tcl_ListObjAppendElement(interp, tcl_result, rowListObj);
00425 }
00426 Tcl_SetObjResult(interp, tcl_result);
00427 return TCL_OK;
00428 #else
00429 Tcl_AppendResult(interp, "CUDA Acceleration not available in this build", NULL);
00430 return TCL_ERROR;
00431 #endif
00432 } else if (!strupncmp(argv[1], "cudadevpool", CMDLEN)) {
00433 #if defined(VMDCUDA)
00434 int N=1;
00435 if (argc == 3) {
00436 if (Tcl_GetInt(interp, argv[2], &N) != TCL_OK) {
00437 Tcl_AppendResult(interp, " in vmdbench cudadevpool", NULL);
00438 return TCL_ERROR;
00439 }
00440 }
00441
00442 wkf_threadpool_t * devpool = app->cuda->get_cuda_devpool();
00443 Tcl_Obj *tcl_result = Tcl_NewListObj(0, NULL);
00444 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("Empty kernel launch latency (usec)", -1));
00445 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("Device pool barrier latency (usec)", -1));
00446 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("Device pool empty run cycle latency (usec)", -1));
00447 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("Device pool tile run latency (usec)", -1));
00448 Tcl_ListObjAppendElement(interp, tcl_result, Tcl_NewStringObj("Device pool GPU kernel tile latency (usec)", -1));
00449
00450 int i;
00451 double kernlaunchlatency, barlatency;
00452 double cyclelatency, tilelatency;
00453 double kernellatency;
00454 for (i=0; i<2; i++) {
00455 vmd_cuda_devpool_latency(devpool, N, &kernlaunchlatency,
00456 &barlatency, &cyclelatency,
00457 &tilelatency, &kernellatency);
00458
00459
00460 if (i < 1)
00461 continue;
00462
00463
00464 Tcl_Obj *rowListObj = Tcl_NewListObj(0, NULL);
00465 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(kernlaunchlatency*1000000));
00466 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(barlatency*1000000));
00467 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(cyclelatency*1000000));
00468 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(tilelatency*1000000));
00469 Tcl_ListObjAppendElement(interp, rowListObj, Tcl_NewDoubleObj(kernellatency*1000000));
00470 Tcl_ListObjAppendElement(interp, tcl_result, rowListObj);
00471 }
00472
00473 Tcl_SetObjResult(interp, tcl_result);
00474 return TCL_OK;
00475 #else
00476 Tcl_AppendResult(interp, "CUDA Acceleration not available in this build", NULL);
00477 return TCL_ERROR;
00478 #endif
00479 } else if (!strupncmp(argv[1], "cudaoocgdsio", CMDLEN)) {
00480 #if defined(VMDCUDA)
00481 int first = 0;
00482 int last = -1;
00483 int step = 1;
00484 int i;
00485 int nfiles = 0;
00486 char **trjfileset = NULL;
00487
00488 if (argc < 2) {
00489 cmd_vmdbench_usage(interp);
00490 return TCL_ERROR;
00491 }
00492 AtomSel *sel = tcl_commands_get_sel(interp, argv[2]);
00493 if (!sel) {
00494 Tcl_AppendResult(interp, "cudaoocgdsio: no atom selection", NULL);
00495 return TCL_ERROR;
00496 }
00497
00498 for (i=3; i<argc; i+=2) {
00499 const char *argvcur = argv[i];
00500 if (!strupncmp(argvcur, "first", CMDLEN)) {
00501 first = atoi(argv[i+1]);
00502 } else if (!strupncmp(argvcur, "last", CMDLEN)) {
00503 last = atoi(argv[i+1]);
00504 } else if (!strupncmp(argvcur, "step", CMDLEN)) {
00505 step = atoi(argv[i+1]);
00506 } else if (!strupncmp(argvcur, "files", CMDLEN)) {
00507 int list_num;
00508 const char **list_strs;
00509 if (Tcl_SplitList(interp, argv[i+1], &list_num, &list_strs) != TCL_OK) {
00510 Tcl_AppendResult(interp, "cudaoocgdsio: bad trajectory file list", NULL);
00511 return TCL_ERROR;
00512 }
00513
00514 int f;
00515 nfiles = list_num;
00516 trjfileset = (char **) calloc(1, nfiles * sizeof(const char *));
00517 for (f=0; f<nfiles; f++) {
00518 trjfileset[f] = strdup(list_strs[f]);
00519 printf("File[%d] '%s'\n", f, trjfileset[f]);
00520 }
00521 Tcl_Free((char *)list_strs);
00522 } else {
00523 Tcl_AppendResult(interp, "cudaoocgdsio: invalid syntax, no such keyword: ", argvcur, NULL);
00524 return TCL_ERROR;
00525 }
00526 }
00527
00528 int ret_val = gpu_ooc_bench(app->cuda->get_cuda_devpool(),
00529 nfiles, (const char **) trjfileset, sel,
00530 first, last, step);
00531
00532 if (ret_val < 0) {
00533 Tcl_AppendResult(interp, "cudaoocgdsio: an error occured", NULL);
00534 return TCL_ERROR;
00535 }
00536
00537 if (trjfileset != NULL) {
00538 int f;
00539 for (f=0; f<nfiles; f++) {
00540 free(trjfileset[f]);
00541 }
00542 free(trjfileset);
00543 }
00544
00545 return TCL_OK;
00546 #else
00547 Tcl_AppendResult(interp, "CUDA Acceleration not available in this build", NULL);
00548 return TCL_ERROR;
00549 #endif
00550 } else {
00551 cmd_vmdbench_usage(interp);
00552 return TCL_ERROR;
00553 }
00554 } else {
00555 cmd_vmdbench_usage(interp);
00556 return TCL_ERROR;
00557 }
00558
00559
00560 return TCL_OK;
00561 }
00562
00563