diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..175ace3 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,81 @@ +cmake_minimum_required (VERSION 3.5) + +project (compose CXX) +set (CMAKE_CXX_STANDARD 11) + +function (prc var) + message ("${var}: ${${var}}") +endfunction () + +find_package (MPI REQUIRED) + +if (Kokkos_DIR) + include (${Kokkos_DIR}/kokkos.cmake) + set (Kokkos_INCLUDE ${Kokkos_DIR}/include) +else () + message (FATAL_ERROR "COMPOSE requires Kokkos_DIR") +endif () + +set (SOURCES + cedr/cedr_caas.cpp + cedr/cedr_local.cpp + cedr/cedr_mpi.cpp + cedr/cedr_qlt.cpp + cedr/cedr_test.cpp + cedr/cedr_test_1d_transport.cpp + cedr/cedr_test_randomized.cpp + cedr/cedr_util.cpp) + +set (HEADERS + cedr/cedr.hpp + cedr/cedr_caas.hpp + cedr/cedr_caas_inl.hpp + cedr/cedr_cdr.hpp + cedr/cedr_kokkos.hpp + cedr/cedr_local.hpp + cedr/cedr_local_inl.hpp + cedr/cedr_mpi.hpp + cedr/cedr_mpi_inl.hpp + cedr/cedr_qlt.hpp + cedr/cedr_qlt_inl.hpp + cedr/cedr_test.hpp + cedr/cedr_test_randomized.hpp + cedr/cedr_util.hpp + siqk/siqk.hpp + siqk/siqk_defs.hpp + siqk/siqk_geometry.hpp + siqk/siqk_intersect.hpp + siqk/siqk_quadrature.hpp + siqk/siqk_search.hpp + siqk/siqk_sqr.hpp) + +if (NOT COMPOSE_TEST_MPIRUN) + set (COMPOSE_TEST_MPIRUN mpirun) +endif () +if (NOT COMPOSE_TEST_NRANK) + set (COMPOSE_TEST_NRANK 8) +endif () + +set (COMPOSE_COMPILE_FLAGS "${MPI_COMPILE_FLAGS} ${KOKKOS_CXXFLAGS} ${CMAKE_CXX_FLAGS}") +set (COMPOSE_LINK_FLAGS "${MPI_LINK_FLAGS} ${KOKKOS_LDFLAGS}") +set (COMPOSE_INCLUDES "${Kokkos_INCLUDE}") +set (COMPOSE_LIBRARIES ${MPI_LIBRARIES} ${KOKKOS_LIBS}) + +prc(MPI_COMPILE_FLAGS) +prc(MPI_LINK_FLAGS) +prc(MPI_LIBRARIES) +add_library (${PROJECT_NAME} ${SOURCES}) +set_target_properties (${PROJECT_NAME} PROPERTIES + COMPILE_FLAGS ${COMPOSE_COMPILE_FLAGS} + LINK_FLAGS ${COMPOSE_LINK_FLAGS}) +target_include_directories (${PROJECT_NAME} PUBLIC cedr siqk) +target_include_directories (${PROJECT_NAME} PRIVATE siqk cedr) +target_include_directories (${PROJECT_NAME} PUBLIC ${COMPOSE_INCLUDES}) +target_link_libraries (${PROJECT_NAME} ${COMPOSE_LIBRARIES}) + +install (TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib) +install (FILES ${HEADERS} DESTINATION include/compose) + +enable_testing () +add_subdirectory(siqk) +add_subdirectory(cedr) diff --git a/README.md b/README.md index 8dec62e..165fdd3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,22 @@ # COMPOSE -Compact Multi-moment Performance-Portable Semi-Lagrangian methods for non-hydrostatic dynamics +Compact Multi-moment Performance-Portable Semi-Lagrangian methods + +COMPOSE provides libraries for semi-Lagrangian transport and, together or +separately, property preservation. + +CEDR: Communication-Efficient Constrained Density Reconstructors. +SIQK: Sphereical Polygon Intersection and Quadrature. + +First, install Kokkos: + https://github.com/kokkos/kokkos +For example, in a typical environment using OpenMP, a simple build line is: + ./kokkos/generate_makefile.bash --with-serial --with-openmp --prefix=/path/to/my/libs --compiler=g++ + make -j8 install + +Second, configure, build, and test COMPOSE: + cmake \ + -D Kokkos_DIR=/path/to/my/kokkos/install \ + -D CMAKE_INSTALL_PREFIX=/path/to/my/compose/install \ + /path/to/compose/repo + make -j8 + ctest diff --git a/cedr/CMakeLists.txt b/cedr/CMakeLists.txt new file mode 100644 index 0000000..f0f5c88 --- /dev/null +++ b/cedr/CMakeLists.txt @@ -0,0 +1,15 @@ +add_executable (cedr_test cedr_test.cpp) +set_target_properties (cedr_test PROPERTIES + COMPILE_FLAGS ${COMPOSE_COMPILE_FLAGS} + LINK_FLAGS ${COMPOSE_LINK_FLAGS}) + +target_include_directories (cedr_test PRIVATE ${COMPOSE_INCLUDES}) +target_link_libraries (cedr_test ${PROJECT_NAME} ${COMPOSE_LIBRARIES}) + +add_test (NAME cedr-test-unit + COMMAND $ -t) +add_test (NAME cedr-test-unit-mpi + COMMAND ${COMPOSE_TEST_MPIRUN} -np ${COMPOSE_TEST_NRANK} + $ -t --proc-random -nc 111 -nt 11) +add_test (NAME cedr-test-t1d + COMMAND $ -t -t1d -nc 111) diff --git a/cedr/Makefile b/cedr/Makefile deleted file mode 100644 index 99fab15..0000000 --- a/cedr/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -include make.inc - -CXXFLAGS=$(opt) -Wall -pedantic -fopenmp -std=c++11 -I$(KOKKOS)/include -DQLT_TIME -LDFLAGS=-fopenmp -L$(KOKKOS)/lib -lkokkos -ldl -LINK_LAPACK_BLAS=-llapack -lblas - -SOURCES=cedr_mpi.cpp cedr_util.cpp cedr_qlt.cpp cedr_caas.cpp cedr_local.cpp \ - cedr_test.cpp cedr_test_randomized.cpp cedr_test_1d_transport.cpp - -OBJECTS=$(SOURCES:.cpp=.o) - -.cpp.o: - $(MPICXX) $(CFLAGS) $(CXXFLAGS) -c $< -o $@ - -all: testcedr - -testcedr: cedr_test.o $(OBJECTS) - $(MPICXX) $(OBJECTS) $(LDFLAGS) -o testcedr - -clean: - rm -f *.o testcedr - -cedr_qlt.o: cedr_mpi.hpp cedr_mpi_inl.hpp cedr_local.hpp cedr_local_inl.hpp \ - cedr_qlt.hpp cedr_qlt_inl.hpp cedr_kokkos.hpp cedr_util.hpp \ - cedr_test_randomized.hpp -cedr_caas.o: cedr_mpi.hpp cedr_mpi_inl.hpp cedr_local.hpp cedr_local_inl.hpp \ - cedr_caas.hpp cedr_caas_inl.hpp cedr_kokkos.hpp cedr_util.hpp \ - cedr_test_randomized.hpp -cedr_test.o: cedr_qlt.hpp cedr_util.hpp -cedr_test_1d_transport.o: cedr_qlt.hpp cedr_util.hpp -cedr_local.o: cedr_local_inl.hpp -cedr_test_randomized.o: cedr_qlt.hpp cedr_util.hpp cedr_test_randomized.hpp diff --git a/cedr/README.md b/cedr/README.md deleted file mode 100644 index 0417972..0000000 --- a/cedr/README.md +++ /dev/null @@ -1,13 +0,0 @@ -For clarity, suppose your your C++ compiler is g++-4.8 in what follows. But it -can be something else. - -1. Get and install the standalone Kokkos TPL: - -$ git clone https://github.com/kokkos/kokkos.git -$ ./kokkos/generate_makefile.bash --with-openmp --ldflags=-fPIC --prefix=/path/to/desired/installation --compiler=g++-4.8 - -2. cp an existing make.inc.* file to one for your machine, say, -make.inc.mymachine. Edit it with machine-specific information. Then - $ ln -s make.inc.machine make.inc - $ make -j2 - $ mpirun -np 4 ./testcedr -t # Look for PASS diff --git a/cedr/cedr_qlt_inl.hpp b/cedr/cedr_qlt_inl.hpp index f07f6db..fb9290f 100644 --- a/cedr/cedr_qlt_inl.hpp +++ b/cedr/cedr_qlt_inl.hpp @@ -38,7 +38,8 @@ void QLT::set_Qm (const Int& lclcellidx, const Int& tracer_idx, cedr_kernel_throw_if(true, "set_Q: invalid problem_type."); } if (problem_type & ProblemType::conserve) { - cedr_kernel_throw_if(Qm_prev < 0, "Qm_prev was not provided to set_Q."); + cedr_kernel_throw_if(Qm_prev < -0.5, + "Qm_prev was not provided to set_Q."); bd[3] = Qm_prev; } } diff --git a/cedr/cedr_test.cpp b/cedr/cedr_test.cpp index ece27e7..ebb76f1 100644 --- a/cedr/cedr_test.cpp +++ b/cedr/cedr_test.cpp @@ -74,7 +74,7 @@ struct InputParser { } // namespace cedr int main (int argc, char** argv) { - int nerr = 0; + int nerr = 0, retval = 0; MPI_Init(&argc, &argv); auto p = cedr::mpi::make_parallel(MPI_COMM_WORLD); srand(p->rank()); @@ -93,15 +93,17 @@ int main (int argc, char** argv) { { int gnerr; cedr::mpi::reduce(*p, &nerr, &gnerr, 1, MPI_SUM, p->root()); + retval = gnerr != 0 ? -1 : 0; if (p->amroot()) std::cout << (gnerr != 0 ? "FAIL" : "PASS") << "\n"; } } catch (const std::exception& e) { if (p->amroot()) std::cerr << e.what(); + retval = -1; } Kokkos::finalize_all(); if (nerr) prc(nerr); MPI_Finalize(); - return 0; + return retval; } diff --git a/cedr/make.inc.ws b/cedr/make.inc.ws deleted file mode 100644 index daeeeff..0000000 --- a/cedr/make.inc.ws +++ /dev/null @@ -1,4 +0,0 @@ -opt= -MPICXX=mpicxx -KOKKOS=/home/ambradl/lib/kokkos/cpu -#KOKKOS=/home/ambradl/lib/kokkos/cpu-serial diff --git a/siqk/CMakeLists.txt b/siqk/CMakeLists.txt new file mode 100644 index 0000000..9ff299c --- /dev/null +++ b/siqk/CMakeLists.txt @@ -0,0 +1,13 @@ +add_executable (siqk_test siqk_test.cpp) +set_target_properties (siqk_test PROPERTIES + COMPILE_FLAGS ${COMPOSE_COMPILE_FLAGS} + LINK_FLAGS ${COMPOSE_LINK_FLAGS}) +target_include_directories (siqk_test PRIVATE ${COMPOSE_INCLUDES}) +target_link_libraries (siqk_test ${COMPOSE_LIBRARIES}) + +configure_file (siqk_runtests.py siqk_runtests.py) + +add_test (NAME siqk-test-area + COMMAND python siqk_runtests.py $ 0) +add_test (NAME siqk-test-cube + COMMAND python siqk_runtests.py $ 1) diff --git a/siqk/Makefile b/siqk/Makefile deleted file mode 100644 index 525107a..0000000 --- a/siqk/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -include make.inc - -CXXFLAGS=$(opt) -Wall -pedantic -fopenmp -std=c++11 -I$(KOKKOS)/include -DSIQK_TIME -Wno-unused-function -LDFLAGS=-fopenmp -L$(KOKKOS)/lib -lkokkos -ldl - -OBJECTS=$(SOURCES:.cpp=.o) - -.cpp.o: - $(CXX) $(CFLAGS) $(CXXFLAGS) -c $< -o $@ - -all: siqk_test - -siqk_test: $(OBJECTS) siqk_test.o - $(CXX) $(OBJECTS) siqk_test.o $(LDFLAGS) -o siqk_test - -clean: - rm -f *.o siqk_test diff --git a/siqk/README.md b/siqk/README.md deleted file mode 100644 index da86fd7..0000000 --- a/siqk/README.md +++ /dev/null @@ -1 +0,0 @@ -Sphere Intersection and Quadrature with Kokkos. diff --git a/siqk/make.inc.amb b/siqk/make.inc.amb deleted file mode 100644 index 71ed8b5..0000000 --- a/siqk/make.inc.amb +++ /dev/null @@ -1,3 +0,0 @@ -opt=-O3 -CXX=g++ -KOKKOS=/home/ambradl/lib/kokkos/cpu diff --git a/siqk/siqk_defs.hpp b/siqk/siqk_defs.hpp index ad3c896..9c3cbd0 100644 --- a/siqk/siqk_defs.hpp +++ b/siqk/siqk_defs.hpp @@ -155,20 +155,20 @@ const_slice (const VT& v, Int i) { return ko::subview(v, i, ko::ALL()); } #else template KOKKOS_FORCEINLINE_FUNCTION typename VT::value_type* -slice (const VT& v, Int i) { return v.ptr_on_device() + v.dimension_1()*i; } +slice (const VT& v, Int i) { return v.data() + v.extent(1)*i; } template KOKKOS_FORCEINLINE_FUNCTION typename VT::const_value_type* -const_slice (const VT& v, Int i) { return v.ptr_on_device() + v.dimension_1()*i; } +const_slice (const VT& v, Int i) { return v.data() + v.extent(1)*i; } #endif // Number of slices in a 2D array, where each row is a slice. template KOKKOS_FORCEINLINE_FUNCTION -Int nslices (const A2D& a) { return static_cast(a.dimension_0()); } +Int nslices (const A2D& a) { return static_cast(a.extent(0)); } // Number of entries in a 2D array's row. template KOKKOS_FORCEINLINE_FUNCTION -Int szslice (const A2D& a) { return static_cast(a.dimension_1()); } +Int szslice (const A2D& a) { return static_cast(a.extent(1)); } template KOKKOS_INLINE_FUNCTION @@ -184,8 +184,19 @@ void resize_and_copy (DV& d, const SV& s, } template -void resize_and_copy (DV& d, const SV& s, - typename std::enable_if::type* = 0) { +void resize_and_copy ( + DV& d, const SV& s, + typename std::enable_if::type* = 0) +{ + ko::resize(d, nslices(s)); + ko::deep_copy(d, s); +} + +template +void resize_and_copy ( + DV& d, const SV& s, + typename std::enable_if::type* = 0) +{ ko::resize(d, nslices(s), szslice(s)); ko::deep_copy(d, s); } diff --git a/siqk/siqk_intersect.hpp b/siqk/siqk_intersect.hpp index d380002..6fcde7b 100644 --- a/siqk/siqk_intersect.hpp +++ b/siqk/siqk_intersect.hpp @@ -195,7 +195,7 @@ void fill_normals (sh::Mesh& m) { // Fill. Idxs::HostMirror en("en", nslices(m.e), szslice(m.e)); ko::deep_copy(en, -1); - Vec3s::HostMirror nml("nml", ne, 3); + Vec3s::HostMirror nml("nml", ne); Int ie = 0; for (Int ip = 0; ip < nslices(m.e); ++ip) for (Int iv = 0; iv < szslice(m.e); ++iv) @@ -248,9 +248,9 @@ class AreaOTFunctor { // In and out vertex lists. Real buf[9*max_nvert]; RawVec3s - vi(buf, max_nvert, 3), - vo(buf + 3*max_nvert, max_nvert, 3), - wrk(buf + 6*max_nvert, max_nvert, 3); + vi(buf, max_nvert), + vo(buf + 3*max_nvert, max_nvert), + wrk(buf + 6*max_nvert, max_nvert); Int ni; ni = 0; for (Int i = 0; i < szslice(e_); ++i) { diff --git a/siqk/siqk_quadrature.hpp b/siqk/siqk_quadrature.hpp index ce602ca..42164ad 100644 --- a/siqk/siqk_quadrature.hpp +++ b/siqk/siqk_quadrature.hpp @@ -566,40 +566,40 @@ class TriangleQuadrature { RawConstArray& weight) const { switch (order) { case 4: - coord = RawConstVec3s(trisym_order4_coord_, 6, 3); + coord = RawConstVec3s(trisym_order4_coord_, 6); weight = RawConstArray(trisym_order4_weight_, 6); break; case 6: - coord = RawConstVec3s(tritay_order6_coord_, 11, 3); + coord = RawConstVec3s(tritay_order6_coord_, 11); weight = RawConstArray(tritay_order6_weight_, 11); break; case 8: - coord = RawConstVec3s(trisym_order8_coord_, 16, 3); + coord = RawConstVec3s(trisym_order8_coord_, 16); weight = RawConstArray(trisym_order8_weight_, 16); break; case 12: #ifdef SIQK_USE_TRITAY12 - coord = RawConstVec3s(tritay_order12_coord_, 32, 3); + coord = RawConstVec3s(tritay_order12_coord_, 32); weight = RawConstArray(tritay_order12_weight_, 32); #else - coord = RawConstVec3s(trisym_order12_coord_, 33, 3); + coord = RawConstVec3s(trisym_order12_coord_, 33); weight = RawConstArray(trisym_order12_weight_, 33); #endif break; case 14: - coord = RawConstVec3s(trisym_order14_coord_, 46, 3); + coord = RawConstVec3s(trisym_order14_coord_, 46); weight = RawConstArray(trisym_order14_weight_, 46); break; case 16: - coord = RawConstVec3s(tritay_order16_coord_, 55, 3); + coord = RawConstVec3s(tritay_order16_coord_, 55); weight = RawConstArray(tritay_order16_weight_, 55); break; case 18: - coord = RawConstVec3s(tritay_order18_coord_, 66, 3); + coord = RawConstVec3s(tritay_order18_coord_, 66); weight = RawConstArray(tritay_order18_weight_, 66); break; case 20: - coord = RawConstVec3s(trisym_order20_coord_, 88, 3); + coord = RawConstVec3s(trisym_order20_coord_, 88); weight = RawConstArray(trisym_order20_weight_, 88); break; default: diff --git a/siqk/siqk_runtests.py b/siqk/siqk_runtests.py index eea9e21..8a05d9a 100755 --- a/siqk/siqk_runtests.py +++ b/siqk/siqk_runtests.py @@ -1,10 +1,12 @@ #!/usr/bin/python -import os +import os, sys quick = True +exe = sys.argv[1] +testno = int(sys.argv[2]) -stride = 1 +stride = 2 biggest = 1111 xlates = [4.2*10**f for f in range(-17, 0, stride)] @@ -17,37 +19,39 @@ fails = [] cnt = 0 -# Test 1 -for n in [4, 20, 40, 79]: - if quick and n > 20: break - for angle in angles: - cmd = ('OMP_NUM_THREADS=8 ./siqk_test --testno 1 --angle {angle:1.15e} -n {n:d}'. - format(angle=angle, n=n)) - stat = os.system(cmd + ' |& grep PASSED &> /dev/null') - if stat: - fails.append(cmd) - else: - cnt += 1 - print len(fails) - -# Test 0 -for n in [4, 50, 511, biggest]: - if quick and n > 50: break - for angle in angles: - for xlate in xlates: - for ylate in ylates: - cmd = ('OMP_NUM_THREADS=8 ./siqk_test --testno 0 --xlate {xlate:1.15e} --ylate {ylate:1.14e} --angle {angle:1.15e} -n {n:d}'. - format(xlate=xlate, ylate=ylate, angle=angle, n=n)) - stat = os.system(cmd + ' |& grep PASSED &> /dev/null') - if stat: - fails.append(cmd) - else: - cnt += 1 - print len(fails) +if testno == 0: + for n in [4, 50, 511, biggest]: + if quick and n > 50: break + for angle in angles: + for xlate in xlates: + for ylate in ylates: + cmd = ('OMP_NUM_THREADS=8 {exe:s} --testno 0 --xlate {xlate:1.15e} --ylate {ylate:1.14e} --angle {angle:1.15e} -n {n:d}'. + format(exe=exe, xlate=xlate, ylate=ylate, angle=angle, n=n)) + stat = os.system(cmd + ' |& grep PASSED &> /dev/null') + if stat: + fails.append(cmd) + else: + cnt += 1 + print len(fails) + +elif testno == 1: + for n in [4, 20, 40, 79]: + if quick and n > 20: break + for angle in angles: + cmd = ('OMP_NUM_THREADS=8 {exe:s} --testno 1 --angle {angle:1.15e} -n {n:d}'. + format(exe=exe, angle=angle, n=n)) + stat = os.system(cmd + ' |& grep PASSED &> /dev/null') + if stat: + fails.append(cmd) + else: + cnt += 1 + print len(fails) if len(fails) > 0: print 'FAILED' for f in fails: print f + sys.exit(-1) else: print 'PASSED ({0:d})'.format(cnt) + sys.exit(0) diff --git a/siqk/siqk_search.hpp b/siqk/siqk_search.hpp index 381ac99..1e517e3 100644 --- a/siqk/siqk_search.hpp +++ b/siqk/siqk_search.hpp @@ -236,7 +236,7 @@ class Octree { // Get OT's bounding box. calc_bb(p, bb_); // Get elements' bounding boxes. - Vec6s::HostMirror ebbs("ebbs", nslices(e), 6); + Vec6s::HostMirror ebbs("ebbs", nslices(e)); calc_bb(p, e, ebbs); // Static element lists for work. Each level has active work space. std::vector buf(max_depth_*nslices(e)); @@ -305,7 +305,7 @@ class Octree { void init_static_ds (const DynNodes nodes, const DynIntList& offsets, const DynIntList& elems) { { - ko::resize(nodes_, nodes.n(), 8); + ko::resize(nodes_, nodes.n()); auto nodes_hm = ko::create_mirror_view(nodes_); for (Int i = 0; i < nodes.n(); ++i) for (Int j = 0; j < 8; ++j) diff --git a/siqk/siqk_test.cpp b/siqk/siqk_test.cpp index 7d73cdf..e08ab2a 100644 --- a/siqk/siqk_test.cpp +++ b/siqk/siqk_test.cpp @@ -35,7 +35,7 @@ static void make_planar_mesh (Vec3s::HostMirror& p, Idxs::HostMirror& e, const Int n) { const Real d = std::sqrt(0.5); ko::resize(e, n*n, 4); - ko::resize(p, (n+1)*(n+1), 3); + ko::resize(p, (n+1)*(n+1)); for (Int iy = 0; iy < n+1; ++iy) for (Int ix = 0; ix < n+1; ++ix) { const auto idx = (n+1)*iy + ix; @@ -111,9 +111,9 @@ static void remove_unused_vertices (Vec3s::HostMirror& p, Idxs::HostMirror& e, for (Int k = 0; k < szslice(e); ++k) e(ei,k) -= adjust[e(ei,k)]; // Remove unused from p. - Vec3s::HostMirror pc("copy", nslices(p), szslice(p)); + Vec3s::HostMirror pc("copy", nslices(p)); ko::deep_copy(pc, p); - ko::resize(p, nslices(p) - rmcnt, szslice(p)); + ko::resize(p, nslices(p) - rmcnt); for (Int i = 0, j = 0; i < nslices(pc); ++i) { if (pc(i,0) == unused) continue; for (Int k = 0; k < szslice(pc); ++k) p(j,k) = pc(i,k); @@ -143,11 +143,11 @@ void make_cubesphere_mesh (Vec3s::HostMirror& p, Idxs::HostMirror& e, Idxs::HostMirror& e_ref = es[0]; make_planar_mesh(p_ref, e_ref, n); ko::resize(e, 6*nslices(e_ref), 4); - ko::resize(p, 6*nslices(p_ref), 3); + ko::resize(p, 6*nslices(p_ref)); for (Int i = 1; i < 6; ++i) { ko::resize(es[i], nslices(e_ref), 4); ko::deep_copy(es[i], e_ref); - ko::resize(ps[i], nslices(p_ref), 3); + ko::resize(ps[i], nslices(p_ref)); ko::deep_copy(ps[i], p_ref); transform_planar_mesh(R[i], xlate[i], ps[i]); } @@ -366,17 +366,17 @@ static Real calc_true_area ( const ConstVec3s::HostMirror& p, const ConstIdxs::HostMirror& e, const bool wm) { - Vec3s::HostMirror clip_poly("clip_poly", 4, 3), poly("poly", 4, 3), - nml("nml", 4, 3); + Vec3s::HostMirror clip_poly("clip_poly", 4), poly("poly", 4), + nml("nml", 4); fill_quad(cp, clip_poly); fill_quad(p, poly); for (Int i = 0; i < 4; ++i) Geo::edge_normal(slice(clip_poly, i), slice(clip_poly, (i+1) % 4), slice(nml, i)); - Vec3s::HostMirror vo("vo", test::max_nvert, 3); + Vec3s::HostMirror vo("vo", test::max_nvert); Int no; { - Vec3s::HostMirror wrk("wrk", test::max_nvert, 3); + Vec3s::HostMirror wrk("wrk", test::max_nvert); sh::clip_against_poly(clip_poly, nml, poly, 4, vo, no, wrk); } if (wm) {