1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
2 // Copyright (c) Lawrence Livermore National Security, LLC and other Ascent
3 // Project developers. See top-level LICENSE AND COPYRIGHT files for dates and
4 // other details. No copyright assignment is required to contribute to Ascent.
5 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
6 
7 //-----------------------------------------------------------------------------
8 ///
9 /// file: t_ascent_render_3d.cpp
10 ///
11 //-----------------------------------------------------------------------------
12 
13 
14 #include "gtest/gtest.h"
15 
16 #include <ascent.hpp>
17 #include <runtimes/ascent_vtkh_data_adapter.hpp>
18 #include <vtkm/cont/testing/MakeTestDataSet.h>
19 #include <iostream>
20 #include <math.h>
21 
22 #include <conduit_blueprint.hpp>
23 
24 #include "t_config.hpp"
25 #include "t_utils.hpp"
26 
27 
28 
29 
30 using namespace std;
31 using namespace conduit;
32 using namespace ascent;
33 
34 
35 index_t EXAMPLE_MESH_SIDE_DIM = 20;
36 
37 
38 //-----------------------------------------------------------------------------
TEST(ascent_data_adapter,vtkm_uniform_2d_to_blueprint)39 TEST(ascent_data_adapter, vtkm_uniform_2d_to_blueprint)
40 {
41     Node n;
42     ascent::about(n);
43     // only run this test if ascent was built with vtkm support
44     if(n["runtimes/ascent/vtkm/status"].as_string() == "disabled")
45     {
46         ASCENT_INFO("Ascent vtkm support disabled, skipping test");
47         return;
48     }
49 
50     vtkm::cont::testing::MakeTestDataSet maker;
51     vtkm::cont::DataSet ds = maker.Make2DUniformDataSet0();
52     conduit::Node blueprint;
53     bool zero_copy = false;
54     std::string topo_name = "topo";
55     VTKHDataAdapter::VTKmToBlueprintDataSet(&ds, blueprint,topo_name, false);
56     conduit::Node info;
57     bool success = conduit::blueprint::verify("mesh",blueprint,info);
58     if(!success) info.print();
59     EXPECT_TRUE(success);
60 }
61 
62 
63 //-----------------------------------------------------------------------------
TEST(ascent_data_adapter,vtkm_uniform_3d_to_blueprint)64 TEST(ascent_data_adapter, vtkm_uniform_3d_to_blueprint)
65 {
66     Node n;
67     ascent::about(n);
68     // only run this test if ascent was built with vtkm support
69     if(n["runtimes/ascent/vtkm/status"].as_string() == "disabled")
70     {
71         ASCENT_INFO("Ascent vtkm support disabled, skipping test");
72         return;
73     }
74 
75     vtkm::cont::testing::MakeTestDataSet maker;
76     vtkm::cont::DataSet ds = maker.Make3DUniformDataSet0();
77     conduit::Node blueprint;
78     bool zero_copy = false;
79     std::string topo_name = "topo";
80     VTKHDataAdapter::VTKmToBlueprintDataSet(&ds, blueprint,topo_name, false);
81     conduit::Node info;
82     bool success = conduit::blueprint::verify("mesh",blueprint,info);
83     if(!success) info.print();
84     EXPECT_TRUE(success);
85 }
86 
87 //-----------------------------------------------------------------------------
TEST(ascent_data_adapter,vtkm_rectilinear_3d_to_blueprint)88 TEST(ascent_data_adapter, vtkm_rectilinear_3d_to_blueprint)
89 {
90     Node n;
91     ascent::about(n);
92     // only run this test if ascent was built with vtkm support
93     if(n["runtimes/ascent/vtkm/status"].as_string() == "disabled")
94     {
95         ASCENT_INFO("Ascent vtkm support disabled, skipping test");
96         return;
97     }
98 
99     vtkm::cont::testing::MakeTestDataSet maker;
100     vtkm::cont::DataSet ds = maker.Make3DRectilinearDataSet0();
101     conduit::Node blueprint;
102     bool zero_copy = false;
103     std::string topo_name = "topo";
104     VTKHDataAdapter::VTKmToBlueprintDataSet(&ds, blueprint,topo_name, false);
105     conduit::Node info;
106     bool success = conduit::blueprint::verify("mesh",blueprint,info);
107     if(!success) info.print();
108     EXPECT_TRUE(success);
109 }
110 
111 
112 //-----------------------------------------------------------------------------
TEST(ascent_data_adapter,vtkm_rectilinear_2d_to_blueprint)113 TEST(ascent_data_adapter, vtkm_rectilinear_2d_to_blueprint)
114 {
115     Node n;
116     ascent::about(n);
117     // only run this test if ascent was built with vtkm support
118     if(n["runtimes/ascent/vtkm/status"].as_string() == "disabled")
119     {
120         ASCENT_INFO("Ascent vtkm support disabled, skipping test");
121         return;
122     }
123 
124     vtkm::cont::testing::MakeTestDataSet maker;
125     vtkm::cont::DataSet ds = maker.Make2DRectilinearDataSet0();
126     conduit::Node blueprint;
127     bool zero_copy = false;
128     std::string topo_name = "topo";
129     VTKHDataAdapter::VTKmToBlueprintDataSet(&ds, blueprint,topo_name, false);
130     conduit::Node info;
131     bool success = conduit::blueprint::verify("mesh",blueprint,info);
132     if(!success) info.print();
133     EXPECT_TRUE(success);
134 }
135 
136 //-----------------------------------------------------------------------------
TEST(ascent_data_adapter,vtkm_explicit_single_type_to_blueprint)137 TEST(ascent_data_adapter, vtkm_explicit_single_type_to_blueprint)
138 {
139     Node n;
140     ascent::about(n);
141     // only run this test if ascent was built with vtkm support
142     if(n["runtimes/ascent/vtkm/status"].as_string() == "disabled")
143     {
144         ASCENT_INFO("Ascent vtkm support disabled, skipping test");
145         return;
146     }
147 
148     vtkm::cont::testing::MakeTestDataSet maker;
149     vtkm::cont::DataSet ds = maker.Make3DExplicitDataSetCowNose();
150     conduit::Node blueprint;
151     bool zero_copy = false;
152     std::string topo_name = "topo";
153     VTKHDataAdapter::VTKmToBlueprintDataSet(&ds, blueprint,topo_name, false);
154     conduit::Node info;
155     bool success = conduit::blueprint::verify("mesh",blueprint,info);
156     if(!success) info.print();
157     EXPECT_TRUE(success);
158 
159 
160     // Write out the data set for debugging
161     blueprint["state/cycle"] = 1;
162     blueprint["state/domain_id"] = 0;
163     string output_path = "";
164     output_path = prepare_output_dir();
165 
166     string output_file = conduit::utils::join_file_path(output_path,"tout_explicit_vtkm_converions");
167 
168     conduit::Node extracts;
169     extracts["e1/type"]  = "relay";
170     extracts["e1/params/path"] = output_file;
171     extracts["e1/params/protocol"] = "blueprint/mesh/hdf5";
172 
173     conduit::Node actions;
174     // add the extracts
175     conduit::Node &add_extracts = actions.append();
176     add_extracts["action"] = "add_extracts";
177     add_extracts["extracts"] = extracts;
178 
179     Node ascent_opts;
180     Ascent ascent;
181     ascent.open(ascent_opts);
182     ascent_opts["runtime"] = "ascent";
183     ascent.publish(blueprint);
184     ascent.execute(actions);
185     ascent.close();
186 
187 }
188 //-----------------------------------------------------------------------------
TEST(ascent_data_adapter,zero_copy_test)189 TEST(ascent_data_adapter, zero_copy_test)
190 {
191     Node n;
192     ascent::about(n);
193     // only run this test if ascent was built with vtkm support
194     if(n["runtimes/ascent/vtkm/status"].as_string() == "disabled")
195     {
196         ASCENT_INFO("Ascent vtkm support disabled, skipping test");
197         return;
198     }
199 
200     //
201     // Create an example mesh.
202     //
203     Node data, verify_info;
204     conduit::blueprint::mesh::examples::braid("hexs",
205                                               EXAMPLE_MESH_SIDE_DIM,
206                                               EXAMPLE_MESH_SIDE_DIM,
207                                               EXAMPLE_MESH_SIDE_DIM,
208                                               data);
209 
210     EXPECT_TRUE(conduit::blueprint::mesh::verify(data,verify_info));
211 
212     ASCENT_INFO("testing zero copy bp -> vtkm -> bp");
213 
214 
215     string output_path = prepare_output_dir();
216     string output_file = conduit::utils::join_file_path(output_path,"tout_contour_extract");
217 
218     //
219     // Create the actions.
220     //
221 
222     conduit::Node pipelines;
223     // pipeline 1
224     pipelines["pl1/f1/type"] = "contour";
225     // filter knobs
226     conduit::Node &contour_params = pipelines["pl1/f1/params"];
227     contour_params["field"] = "braid";
228     contour_params["iso_values"] = 0.;
229 
230     conduit::Node extracts;
231     extracts["e1/type"]  = "relay";
232     extracts["e1/pipeline"]  = "pl1";
233     extracts["e1/params/path"] = output_file;
234     extracts["e1/params/protocol"] = "blueprint/mesh/hdf5";
235 
236     conduit::Node actions;
237     // add the pipeline
238     conduit::Node &add_pipelines = actions.append();
239     add_pipelines["action"] = "add_pipelines";
240     add_pipelines["pipelines"] = pipelines;
241 
242     conduit::Node &add_extracts = actions.append();
243     add_extracts["action"] = "add_extracts";
244     add_extracts["extracts"] = extracts;
245 
246     //
247     // Run Ascent
248     //
249 
250     Ascent ascent;
251 
252     Node ascent_opts;
253     ascent_opts["runtime/type"] = "ascent";
254     ascent.open(ascent_opts);
255     ascent.publish(data);
256     ascent.execute(actions);
257     ascent.close();
258 }
259 
260 
261 //-----------------------------------------------------------------------------
TEST(ascent_data_adapter,consistent_domain_ids_check)262 TEST(ascent_data_adapter, consistent_domain_ids_check)
263 {
264     Node n;
265     ascent::about(n);
266     // only run this test if ascent was built with vtkm support
267     if(n["runtimes/ascent/vtkm/status"].as_string() == "disabled")
268     {
269         ASCENT_INFO("Ascent vtkm support disabled, skipping test");
270         return;
271     }
272 
273     Node multi_dom;
274     Node &mesh1 = multi_dom.append();
275     Node &mesh2 = multi_dom.append();
276     conduit::blueprint::mesh::examples::braid("hexs",
277                                               2,
278                                               2,
279                                               2,
280                                               mesh1);
281     conduit::blueprint::mesh::examples::braid("hexs",
282                                               2,
283                                               2,
284                                               2,
285                                               mesh2);
286     mesh1.remove("state");
287     mesh2["state/domain_id"] = 1;
288     bool consistent_ids = false;
289 
290 
291     //
292     // Publish inconsistent ids to Ascent
293     //
294 
295     Ascent ascent;
296 
297     Node ascent_opts;
298     ascent_opts["runtime/type"] = "ascent";
299     ascent_opts["exceptions"] = "forward";
300     ascent.open(ascent_opts);
301     EXPECT_THROW(ascent.publish(multi_dom),conduit::Error);
302     ascent.close();
303 }
304 
305 //-----------------------------------------------------------------------------
TEST(ascent_data_adapter,interleaved_3d)306 TEST(ascent_data_adapter, interleaved_3d)
307 {
308     // CYRUSH: I tried recreate an issue with interleaved coords
309     // we hit in AMReX with this test case, however it does not
310     // replicate it  (rendering still works with the vtk-m interleaved logic)
311     // It is still a good basic interleaved test case.
312     Node n;
313     ascent::about(n);
314     // only run this test if ascent was built with vtkm support
315     if(n["runtimes/ascent/vtkm/status"].as_string() == "disabled")
316     {
317         ASCENT_INFO("Ascent vtkm support disabled, skipping test");
318         return;
319     }
320 
321     Node mesh;
322     conduit::blueprint::mesh::examples::braid("points",
323                                               10,
324                                               10,
325                                               10,
326                                               mesh);
327 
328     // change the x,y,z coords to interleaved
329 
330     Node icoords;
331     conduit::blueprint::mcarray::to_interleaved(mesh["coordsets/coords/values"],icoords);
332     mesh["coordsets/coords/values"].set_external(icoords);
333 
334     EXPECT_TRUE(conduit::blueprint::mcarray::is_interleaved(mesh["coordsets/coords/values"]));
335 
336     string output_path = prepare_output_dir();
337     string output_file = conduit::utils::join_file_path(output_path,
338                                     "tout_render_3d_interleaved");
339 
340     // remove old images before rendering
341     remove_test_image(output_file);
342 
343 
344     conduit::Node scenes;
345     scenes["s1/plots/p1/type"]  = "pseudocolor";
346     scenes["s1/plots/p1/field"] = "braid";
347     scenes["s1/image_prefix"] = output_file;
348 
349     conduit::Node actions;
350     conduit::Node &add_plots = actions.append();
351     add_plots["action"] = "add_scenes";
352     add_plots["scenes"] = scenes;
353 
354     // make sure we can render interleaved data
355     Ascent ascent;
356     Node ascent_opts;
357     ascent_opts["runtime/type"] = "ascent";
358     ascent.open(ascent_opts);
359     ascent.publish(mesh);
360     ascent.execute(actions);
361     ascent.close();
362 
363     // NOTE: RELAXED TOLERANCE TO FROM default
364     //       to mitigate differences between platforms
365     EXPECT_TRUE(check_test_image(output_file,0.01f));
366 }
367 
368 //-----------------------------------------------------------------------------
TEST(ascent_multi_topo,adapter_test)369 TEST(ascent_multi_topo, adapter_test)
370 {
371     Node n;
372     ascent::about(n);
373     // only run this test if ascent was built with vtkm support
374     if(n["runtimes/ascent/vtkm/status"].as_string() == "disabled")
375     {
376         ASCENT_INFO("Ascent vtkm support disabled, skipping test");
377         return;
378     }
379 
380     ASCENT_INFO("Testing round trip of multi_topo");
381     //
382     // Create an example mesh convert it, and convert it back.
383     //
384     Node data;
385     build_multi_topo(data, EXAMPLE_MESH_SIDE_DIM);
386 
387     VTKHCollection* collection = VTKHDataAdapter::BlueprintToVTKHCollection(data,true);
388 
389     Node out_data;
390     VTKHDataAdapter::VTKHCollectionToBlueprintDataSet(collection, out_data);
391 
392     Node verify_info;
393     EXPECT_TRUE(conduit::blueprint::mesh::verify(out_data, verify_info));
394     delete collection;
395 }
396 
397 //-----------------------------------------------------------------------------
main(int argc,char * argv[])398 int main(int argc, char* argv[])
399 {
400     int result = 0;
401 
402     ::testing::InitGoogleTest(&argc, argv);
403 
404     // allow override of the data size via the command line
405     if(argc == 2)
406     {
407         EXAMPLE_MESH_SIDE_DIM = atoi(argv[1]);
408     }
409 
410     result = RUN_ALL_TESTS();
411     return result;
412 }
413 
414 
415