• No results found

THE SD&A PROPOSAL IS A WORKABLE FIRST STEP

Como refuerzo de los resultados experimentales, realizamos una serie de simu- laciones de Monte Carlo correspondientes a los experimentos usando CUDAMCFL. La geometría del medio y la inclusión, así como sus propiedades ópticas, son análo- gas a las usadas para los experimentos previos.

Se simularon dos casos: fantoma sin cobertura, y fantoma con vidrio más cre- ma. Para este último, la simulación se construyó usando un medio de dos capas: fantoma y vidrio, suponiendo que el IM es suficientemente bueno.

La Figura 6.18 muestra el resultado de las simulaciones, comparadas con el caso experimental del fantoma sin cobertura. Se puede ver que, más allá de errores experimentales, MC concuerda adecuadamente con los experimentos.

Modulación normali

zada

Posición angular ɑ

j

[Grad.]

Fig. 6.18: Modulaciones simuladas para diferentes configuraciones de la interfaz, y dife- rentes posiciones de la inclusión.

Parte IV

7

Conclusiones y trabajo futuro

Contempla cada camino de cerca, entonces hazte esta pregunta crucial: ¿me lleva el corazón por esta ruta? Si lo hace, entonces el camino es bueno. Si no es así, es inútil.

Carlos Castaneda

Las enseñanzas de Don Juan

El objetivo planteado al inicio del Trabajo Doctoral que se expone en la pre- sente Tesis, fue avanzar en el estudio de la ciencia necesaria para el desarrollo de un sistema de diagnóstico por imágenes que haga uso de radiación NIR mediante reflectancia difusa de campo completo valiéndose, además, de marcadores fluores- centes.

Este trabajo se focalizó entonces en el estudio de la formación de imágenes de inclusiones inmersas en medios turbios utilizando fuentes de onda continua y geometría de reflectancia. El objetivo mediato es proveer una técnica que permita realizar mamografías ópticas que utilizan radiación no ionizante, y maximizando el confort del paciente. El precio que se paga por ello es la pérdida de resolución 3D. Sin embargo, la incorporación de un agente fluorescente permite mejorar la discriminación de lesiones, sobre todo si se considera la farmacocinética de algunas moléculas fluorescentes como la ICG.

Si bien el marco conceptual del transporte de radiación NIR en medios biológi- cos estaba muy bien desarrollado y ya había sido aplicado a un número de técnicas diagnósticas más o menos complejas, la aquí propuesta no había sido objeto de mucha atención a pesar de contar con características que la hacen ventajosa en una variedad de situaciones. Entre otras ventajas, requiere equipamiento sencillo y barato (incluso comparado con otras técnicas basadas en radiación NIR) y el proce- samiento de los datos no resulta necesariamente costoso computacionalmente.

En esta línea, luego de hacer un repaso de los conceptos y términos necesa- rios para afrontar la lectura y compresión del resto del trabajo en el Capítulo 1, se presentó la idea y principios básicos de la técnica propuesta, de la forma que luego dio inicio a la investigación subsiguiente. La misma se puede resumir en dos partes: formulación y estudio de la propuesta general, junto a la descripción de su configuración experimental y de los efectos de posibles inclusiones absorbentes y/o

fluorescentes por sobre la medición externa; y un proceso de normalización que realce estos últimos efectos, dotando de practicidad concreta a la propuesta.

Dicha normalización, descripta en la Sección 2.1 es imprescindible para la lo- calización de la lesiones y la construcción de una imagen que pueda servir para un diagnóstico directo. El procedimiento propuesto es sencillo pero innovador. Se basa en la toma de múltiples imágenes desde diferentes perspectivas que permiten construir una muy buena aproximación al fondo homogéneo necesario para norma- lizar las medidas, sin necesidad de aproximaciones o inferencias a priori sobre el medio. Esta forma de generar la imagen de referencia también ayuda a minimizar errores experimentales (efectos de iluminación esférica, aberraciones del sistema de medición, fuentes de luz indeseadas, etcétera) que puedan afectar el resultado final.

Una vez formada la idea básica, se avanzó en su caracterización y estudio de- tallado. Prontamente, se hizo evidente que algunas de las herramientas necesarias aún no estaban disponibles. En consecuencia, una porción muy importante del tra- bajo doctoral se enfocó en el estudio detallado del modelo teórico, junto a sus límites de validez, y en el desarrollo e implementación de un algoritmo de Monte Carlo con la capacidad de simular los fundamentos de la propuesta.

Se eligió profundizar en los códigos Monte Carlo como herramienta para poder tener acceso a geometrías más diversas con la posibilidad de poder simular medios con inclusiones de forma y propiedades ópticas arbitrarias.

El algoritmo desarrollado con ese propósito, presentado en la Sección 4.3 y llamado CUDAMCFL, constituye un aporte de suma importancia a la comunidad científica ya que no existía ningún código que permita simular medios absorben- tes y fluorescentes de complejidad arbitraria mediante Monte Carlo. Su desarrollo requirió una gran cantidad de horas de investigación y programación así como de validación y optimización.

El resultado fue un software validado por la comunidad científica y distribuido bajo licencia de software libre, de gran flexibilidad. El mismo constituye una herra- mienta muy valiosa para la caracterización de la técnica de reflectancia difusa en configuraciones imposibles de realizar experimentalmente y con completo control de las diferentes variables en juego. En el presente trabajo se describió en detalle el trabajo realizado en el desarrollo, prueba y validación de CUDAMCFL y se muestra un ejemplo de una simulación importante para la caracterización de la técnica de reflectancia difusa que no era posible con los códigos previos.

Presentada la propuesta y las herramientas desarrolladas para su investigación, se mostraron seguidamente, en el Capítulo 5, experimentos de validación de la téc- nica. Los mismos fueron realizados en fantomas que recrean las propiedades ópticas

esperables en casos de interés clínico. El objetivo fue verificar que es posible detec- tar, localizar, y caracterizar inicialmente la presencia de lesiones fluorescentes y ab- sorbentes. Se eligieron configuraciones experimentales deliberadamente complejas como prueba de estrés de la técnica. La diferencia de concentración de fluoróforos y absorbentes entre medio e inclusión, tamaño y posición de la misma, y caracte- rísticas fluorescentes del medio fueron significativamente más exigentes que la que habitualmente es encontrada en la bibliografía para otras técnicas.

Los resultados mostraron que la propuesta es viable incluso con las limitaciones técnicas de los medios de captura de imágenes y la baja eficiencia cuántica del marcador fluorescente elegido. Inclusiones de 1cm de diámetro son detectables hasta1,75cm de profundidad tanto en absorción como en fluorescencia. Además, al contar con ambas imágenes, su combinación permite mejorar la estadística y el contraste de la medición. Dado que dentro de esta “inclusión” se encontraría no sólo el tumor propiamente dicho sino también, y en especial, la vascularización que lo alimenta, es un resultado alentador para la detección de neoplasmas incipientes.

Seguidamente, con el incentivo de la validación experimental y valiéndonos de las herramientas desarrolladasad-hoc, en el Capítulo 6 se indagaron detalles más específicos necesarios para una implementación práctica de la técnica. Se presen- tó un análisis novedoso de la sensibilidad de un sistema de reflectancia difusa de campo completo, haciendo hincapié en los desafíos introducidos por el uso de una fuente puntual. Usando el modelo teórico se construyó un mapa de sensibilidad que, además de cuantificar la detectabilidad de las inclusiones, puede ser usado para incrementar la resolución de la técnica.

Con este mapa de sensibilidad, y con el objetivo de corregir las limitaciones antes mencionadas, se introdujo un nuevo protocolo de toma de imágenes y norma- lización. El mismo fue validado mediante Monte Carlo, simulando completamente el proceso tal cual podría ser aplicable en un prototipo. Así podemos mostrar que este protocolo es capaz de localizar y resolver inclusiones de variadas formas y con una sensibilidad plana en el espacio de interés.

Avanzando en la recuperación de información de la inclusión, mostramos lue- go en la Sección 6.3 un procedimiento que permite inferir una razonable aproxima- ción sobre la profundidad. Mostramos que si bien la reflectancia difusa de campo completo no llega a ser un sistema tomográfico, es posible recuperar una buena aproximación a la posición 3D de posibles lesiones. Finalmente, en la Sección 6.4 estudiamos cómo minimizar los efectos negativos de la interfaz entre el tejido a es- tudiar y el ambiente. Valiéndonos de datos experimentales y simulaciones de Monte Carlo presentamos una solución simple y económica para la implementación prácti- ca de la misma.

En resumen, como aportes de esta tesis:

Se estudiaron los límites del modelo difusivo y la transición entre el régimen balístico y el difusivo.

De desarrolló un software para la simulación por Monte Carlo del transporte difusivo de fotones en medios turbios fluorescentes con inclusiones, ofrecido en calidad de Software Libre.

Se propuso y validó experimentalmente una técnica de normalización basada en información proveniente solamente de datos de medición.

Se presentó un mecanismo para la obtención de información 3D de las lesio- nes.

Se estudiaron los efectos de la interfaz mecánica entre el tejido a estudiar y el medio para casos reales.

Los resultados obtenidos solidifican la idea de que la formación de imágenes diagnósticas usando reflectancia difusa de campo completo usando radiación NIR es un buen complemento de los métodos ya establecidos. Más allá de las ventajas radicadas en el uso de radiación NIR y que son compartidas por otras técnicas de óptica biomédica de medios turbios, la aquí presentada destaca por su relativa simplicidad y bajo costo.

Estos estudios se reflejan en cinco trabajos publicados en revistas con referato internacional [53, 16, 39, 77, 86], numerosas comunicaciones a congresos tanto nacionales como internacionales, futuras líneas de trabajo y herramientas útiles para la comunidad científica.

7.1

Trabajo futuro

Los principales resultados de los estudios realizados durante la presente Tesis un número de desafíos para trabajos futuros, así como la posibilidad de construir a partir de ellos un equipo prototipo a nivel laboratorio para decidir sobre la utilidad clínica del enfoque planteado.

En consecuencia, y como trabajo que continúe el aquí presentado, se propo- ne:

Analizar y determinar los requisitos de formación de imagen, con el objeti- vo de cuantificar las características que debe cumplir el sensor CCD/IMCC- D/sCCD a utilizar.

Desarrollar protocolos de procesamiento de imágenes que tengan en cuenta el modelo físico y los posibles requisitos clínicos.

Caracterizar las diferentes estrategias de toma de múltiples exposiciones desa- rrolladas previamente, apuntando a la construcción futura de un dispositivo automático de captura.

Estudiar el uso de diferentes agentes de contraste, como nanorods de oro, cuantificando las cantidades detectables por la técnica y evaluando formas de determinar su localización y concentración en el medio a estudiar.

Investigar el comportamiento de láseres de diferentes longitudes de onda. Los mismos podrán ser utilizados para explorar diferentes componentes biológi- cos de los tejidos (por ejemplo635nm,785nmy830nmpara la hemoglobina, 915nmpara la grasa).

Identificar y cuantificar los límites de detectabilidad y las características re- cuperables para diferentes tipos de inhomogeneidades patológicas, utilizando experimentalmente fantomas de propiedades ópticas y geometrías conocidas, como así también simulaciones que complementen las mediciones.

Finalmente, se apunta al desarrollo de un sistema prototipo que pueda, en una futura etapa, ser utilizado conjuntamente con investigadores del área de la medi- cina y la veterinaria como paso indispensable para la caracterización médica de la técnica. Dada su complejidad, naturaleza interdisciplinaria, y limitaciones de ins- trumental y presupuesto, este trabajo colaborativo quedó por fuera de los límites del presente trabajo. Es, sin embargo, requisito necesario para transferir a la socie- dad los frutos de años de trabajo en investigación básica y aplicada desarrollada por nuestro grupo de investigación y el presente plan de trabajo es un paso muy importante en esa dirección.

Parte V

8

Salida del

profiler

Premature optimization is the root of all evil.

Sir Tony Hoare

1 ==1363== NVPROF is profiling process 1363, command: ./cuda_fl inclusion2-v2-3d-gs1-fast.mci

2 ==1363== Profiling application: ./cuda_fl inclusion2-v2-3d-gs1-fast.mci

3 ==1363== Profiling result:

4 Time( %) Time Calls Avg Min Max Name

5 99.58 % 71.0496s 2217 32.048ms 6.3998ms 148.63ms MCd3D(MemStruct)

6 0.26 % 185.72ms 12438 14.931us 1.2480us 63.620us [CUDA memcpy DtoH]

7 0.09 % 64.028ms 6003 10.666us 2.4000us 21.121us [CUDA memset]

8 0.05 % 35.759ms 42021 850ns 512ns 8.1280us [CUDA memcpy HtoD]

9 0.02 % 16.837ms 2001 8.4140us 6.6240us 9.4410us LaunchPhoton_Global(MemStruct)

10

11 ==1363== API calls:

12 Time( %) Time Calls Avg Min Max Name

13 61.78 % 2.8e+03s 4218 661.22ms 3.4690us 26.7338s cudaThreadSynchronize

14 36.48 % 1.6e+03s 22443 73.386ms 3.8060us 26.6063s cudaMemcpy

15 1.18 % 53.2249s 32016 1.6624ms 2.9460us 26.5718s cudaMemcpyToSymbol

16 0.54 % 24.4294s 18009 1.3565ms 4.2110us 22.6391s cudaMalloc

17 0.02 % 900.31ms 18009 49.992us 3.9560us 419.35us cudaFree

18 0.00 % 75.886ms 6003 12.641us 5.2570us 111.10us cudaMemset

19 0.00 % 39.358ms 4218 9.3300us 4.8350us 38.731us cudaLaunch

20 0.00 % 2.0379ms 4218 483ns 186ns 9.1130us cudaGetLastError

21 0.00 % 1.8967ms 4218 449ns 158ns 191.31us cudaConfigureCall

22 0.00 % 1.3732ms 4218 325ns 151ns 8.8000us cudaSetupArgument

23 0.00 % 166.88us 91 1.8330us 124ns 68.760us cuDeviceGetAttribute

24 0.00 % 65.881us 1 65.881us 65.881us 65.881us cuDeviceTotalMem

25 0.00 % 22.471us 1 22.471us 22.471us 22.471us cuDeviceGetName

26 0.00 % 1.9430us 3 647ns 148ns 1.0530us cuDeviceGetCount

27 0.00 % 815ns 3 271ns 198ns 362ns cuDeviceGet

La gran mayoría del tiempo de cómputo se gasta en MCd3D, la función kernel que hace el transporte de fotones. Sin embargo es notable quecudaThreadSynchronize()

es, por mucho, la API más llamada. Esta función de CUDA es ejecutada cada vez que queremos asegurarnos que todos los hilos están sincronizados y, en CUDAMCFL, es usada al final de cada loop de la simulación de transporte “esperará” que todos los fotones terminen. Sin embargo, su importancia está sobreestimada ya que en un

dado momento, incluso cuando algunos hilos pueden estar esperando, la mayoría está corriendo.

Como el número de eventos de scattering que cada fotón va a sufrir es aleatorio y desconocido, el tiempo que cada hilo va a estar ejecutándose puede variar signi- ficativamente. En la presente versión de CUDAMCFL, cada fuente de fluorescencia (cada voxel de la matriz densidad de fotones) se trata como una nueva simulación y una llamada a cudaThreadSynchronize es usada al final de cada una. De esta manera, algo del poder de computo se desperdicia mientras los hilos más rápidos esperan a que los más lentos terminan.

9

Códigos fuente

Unfortunately, no one can be told what The Matrix is. You’ll have to see it for yourself.

Morpheus The Matrix

9.1

CUDAMCFL

9.1.1

Main

1 ///////////////////////////////////////////////////////////// 2 //

3 // Monte Carlo simulation software for light propagation in fluorescent turbid media,

4 // accelerated by GPU (graphic processing unit).

5 // The code is based on previous work by Alerstam et al and Wang et al,

6 // with the addition of a voxelized medium without symmetries and with an

7 // inhomogeneous distribution of absorbers and fluorescent marker

8 //

9 ///////////////////////////////////////////////////////////////

10

11 /* This file is part of CUDAMCFL.

12

13 CUDAMCFL is free software: you can redistribute it and/or modify

14 it under the terms of the GNU General Public License as published by

15 the Free Software Foundation, either version 3 of the License, or

16 (at your option) any later version.

17

18 CUDAMCFL is distributed in the hope that it will be useful,

19 but WITHOUT ANY WARRANTY; without even the implied warranty of

20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

21 GNU General Public License for more details.

22

23 You should have received a copy of the GNU General Public License

24 along with CUDAMCFL. If not, see <http://www.gnu.org/licenses/>.

25 */

26

27 #include "CUDAMCFL.h"

28 #include "cutil.h"

29 //#include <float.h> //for FLT_MAX

30 #include <limits.h>

31 #include <stdio.h>

32 #include "cuda_profiler_api.h"

33

34 __device__ __constant__ unsigned long long num_photons_dc[1];

35 __device__ __constant__ unsigned int n_layers_dc[1];

36 __device__ __constant__ unsigned int n_bulks_dc[1];

37 __device__ __constant__ unsigned int start_weight_dc[1];

38 __device__ __constant__ LayerStruct layers_dc[MAX_LAYERS];

39 __device__ __constant__ BulkStruct bulks_dc[MAX_LAYERS];

40 __device__ __constant__ DetStruct det_dc[1];

41 __device__ __constant__ IncStruct inclusion_dc[1];

42 __device__ __constant__ unsigned int ignoreAdetection_dc[1];

43 __device__ __constant__ unsigned int fhd_activated_dc[1];

44 __device__ __constant__ unsigned int bulk_method_dc[1];

45 __device__ __constant__ float xi_dc[1];

46 __device__ __constant__ float yi_dc[1];

47 __device__ __constant__ float zi_dc[1];

48 __device__ __constant__ float dir_dc[1];

49 __device__ __constant__ float esp_dc[1];

50 __device__ __constant__ unsigned int grid_size_dc[1];

51 52 #include "CUDAMCFLio.cu" 53 #include "CUDAMCFLmem.cu" 54 #include "CUDAMCFLrng.cu" 55 #include "CUDAMCFLtransport.cu" 56

57 // wrapper for device code - FHD Simulation

58 unsigned long long DoOneSimulation(SimulationStruct *simulation, unsigned long long *x,

59 unsigned int *a, double *tempfhd) {

60 MemStruct DeviceMem;

61 MemStruct HostMem;

62 unsigned int threads_active_total = 1;

63 unsigned int i, ii;

64

65 // Output matrix size

66 const int num_x = (int)(4 * (simulation->esp) * (float)simulation->grid_size);

67 const int num_y = (int)(4 * (simulation->esp) * (float)simulation->grid_size);

68 const int num_z = (int)((simulation->esp) * (float)simulation->grid_size);

69 const int fhd_size = num_x * num_y * num_z;

70

71 cudaError_t cudastat;

72 clock_t time1, time2;

73

74 // Start the clock

75 time1 = clock();

76

77 // x and a are already initialised in memory

78 HostMem.x = x;

79 HostMem.a = a;

80

82

83 InitDCMem(simulation);

84

85 dim3 dimBlock(NUM_THREADS_PER_BLOCK);

86 dim3 dimGrid(NUM_BLOCKS);

87 int blockSize; // The launch configurator returned block size

88 int minGridSize; // The minimum grid size needed to achieve the

89 // maximum occupancy for a full device launch

90 //int gridSize; // The actual grid size needed, based on input size

91

92 cudaOccupancyMaxPotentialBlockSize( &minGridSize, &blockSize,

93 MCd3D, 0, 0);

94 printf ("Grid size: %i, Block size: %i \n\n", minGridSize, blockSize);

95 96

97 LaunchPhoton_Global<<<dimGrid, dimBlock>>>(DeviceMem);

98 //LaunchPhoton_Global<<<minGridSize, blockSize>>>(DeviceMem);

99 CUDA_SAFE_CALL(cudaThreadSynchronize()); // Wait for all threads to finish

100 cudastat = cudaGetLastError(); // Check if there was an error

101 if (cudastat)

102 printf("Error code= %i, %s.\n", cudastat, cudaGetErrorString(cudastat));

103

104 i = 0;

105 while (threads_active_total > 0) {

106 i++;

107 // run the kernel

108 if (simulation->bulk_method == 1){ 109 MCd<<<dimGrid, dimBlock>>>(DeviceMem); 110 //MCd<<<minGridSize, blockSize>>>(DeviceMem); 111 112 } 113 else if (simulation->bulk_method == 2) { 114 115 MCd3D<<<dimGrid, dimBlock>>>(DeviceMem); 116 //MCd3D<<<minGridSize, blockSize>>>(DeviceMem); 117 } 118

119 CUDA_SAFE_CALL(cudaThreadSynchronize()); // Wait for all threads to finish

120 cudastat = cudaGetLastError(); // Check if there was an error

121 if (cudastat)

122 printf("Error code= %i, %s.\n", cudastat, cudaGetErrorString(cudastat));

123

124 // Copy thread_active from device to host

125 CUDA_SAFE_CALL(cudaMemcpy(HostMem.thread_active, DeviceMem.thread_active,

126 NUM_THREADS * sizeof(unsigned int),

127 cudaMemcpyDeviceToHost));

128 threads_active_total = 0;

129 for (ii = 0; ii < NUM_THREADS; ii++)

130 threads_active_total += HostMem.thread_active[ii];

131

132 CUDA_SAFE_CALL(cudaMemcpy(HostMem.num_terminated_photons,

133 DeviceMem.num_terminated_photons,

134 sizeof(unsigned long long), cudaMemcpyDeviceToHost));

135 if (i == 100)

136 printf("Estimated PHD simulation time: %.0f secs.\n\n",

137 (double)(clock() - time1) / CLOCKS_PER_SEC *

138 (double)(simulation->number_of_photons /

139 *HostMem.num_terminated_photons));

140 // if (fmod(i, 200u) == 0) printf("."); fflush(stdout);

141 if (i % 100 == 0) printf("."); fflush(stdout);

142 if (i % 2000 == 0)

143 printf("\nRun %u, %llu photons simulated\n", i,

144 *HostMem.num_terminated_photons);

145 }

146

147 CopyDeviceToHostMem(&HostMem, &DeviceMem, simulation);

148

149 time2 = clock();

150

151 printf("\nSimulation time: %.2f sec\n\n",

152 (double)(time2 - time1) / CLOCKS_PER_SEC);

153

154 printf("Writing excitation results...\n");

155 Write_Simulation_Results(&HostMem, simulation, time2-time1);

156 printf("PHD Simulation done!\n");

157

158 unsigned long long photons_finished = *HostMem.num_terminated_photons;

159

160 // Normalize and write output matrix

161 for (int xyz = 0; xyz < fhd_size; xyz++) {

162 tempfhd[xyz] = ((double)HostMem.fhd[xyz]/(0xFFFFFFFF*photons_finished));

163 }

164

165 printf ("Photons simulated: %llu\n\n", photons_finished);

166 FreeMemStructs(&HostMem, &DeviceMem);

167 return photons_finished;

168 }

169

170 // wrapper for device code - fluorescence Simulation

171 unsigned long long DoOneSimulationFl(SimulationStruct *simulation, unsigned long long *x,

172 unsigned int *a, unsigned long long *tempvoxelR, unsigned long long *tempvoxelT) {

173 MemStruct DeviceMem;

174 MemStruct HostMem;

175 unsigned int threads_active_total = 1;

176 unsigned int i, ii;

177

178 // Size of output matrix

179 const int nx2 = simulation->det.nx;

180 const int ny2 = simulation->det.ny;

182

183 cudaError_t cudastat;

184

185 // x and a are already initialised in memory

186 HostMem.x = x;

187 HostMem.a = a;

188

189 InitMemStructs(&HostMem, &DeviceMem, simulation);

190

191 InitDCMem(simulation);

192

193 dim3 dimBlock(NUM_THREADS_PER_BLOCK);

194 dim3 dimGrid(NUM_BLOCKS);

195 int blockSize; // The launch configurator returned block size

196 int minGridSize; // The minimum grid size needed to achieve the

197 // maximum occupancy for a full device launch

198 //int gridSize; // The actual grid size needed, based on input size T

199

200 cudaOccupancyMaxPotentialBlockSize( &minGridSize, &blockSize,

201 MCd, 0, 0); //TODO

202 //printf ("Grid size: %i, Block size: %i \n\n", minGridSize, blockSize);

203

204 LaunchPhoton_Global<<<dimGrid, dimBlock>>>(DeviceMem);

205 //LaunchPhoton_Global<<<minGridSize, blockSize>>>(DeviceMem);

206

207 CUDA_SAFE_CALL(cudaThreadSynchronize()); // Wait for all threads to finish

208 cudastat = cudaGetLastError(); // Check if there was an error

209 if (cudastat)

210 printf("Error code= %i, %s.\n", cudastat, cudaGetErrorString(cudastat));

211

212 i = 0;

213 while (threads_active_total > 0) {

214 i++;

215 // run the kernel

216 if (simulation->bulk_method == 1){ 217 MCd<<<dimGrid, dimBlock>>>(DeviceMem); 218 //MCd<<<minGridSize, blockSize>>>(DeviceMem); 219 220 } 221 else if (simulation->bulk_method == 2) { 222 MCd3D<<<dimGrid, dimBlock>>>(DeviceMem); 223 //MCd3D<<<minGridSize, blockSize>>>(DeviceMem); 224 } 225

226 CUDA_SAFE_CALL(cudaThreadSynchronize()); // Wait for all threads to finish

227 cudastat = cudaGetLastError(); // Check if there was an error

Related documents