00001 /*************************************************************************** 00002 *cr 00003 *cr (C) Copyright 1995-2019 The Board of Trustees of the 00004 *cr University of Illinois 00005 *cr All Rights Reserved 00006 *cr 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * RCS INFORMATION: 00011 * 00012 * $RCSfile: cmd_vmdbench.C,v $ 00013 * $Author: johns $ $Locker: $ $State: Exp $ 00014 * $Revision: 1.29 $ $Date: 2020年07月26日 06:22:53 $ 00015 * 00016 *************************************************************************** 00017 * DESCRIPTION: 00018 * text commands for benchmarking hardware performance 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; // need VMDApp ptr GPU threadpool access 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 // handle optional device list arguments 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 // handle optional device list arguments 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 // handle optional device list arguments 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 // do one warmup pass before we report the benchmark numbers 00460 if (i < 1) 00461 continue; 00462 00463 // report the results 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; // start with first frame by default 00482 int last = -1; // finish with last frame by default 00483 int step = 1; // use all frames by default 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 // if here, everything worked out ok 00560 return TCL_OK; 00561 } 00562 00563