Changeset 5d57155
- Timestamp:
- 09/25/17 16:15:39 (7 years ago)
- Branches:
- master, pympi
- Children:
- b02d091
- Parents:
- fb69232
- git-author:
- Hal Finkel <hfinkel@…> (09/25/17 16:15:39)
- git-committer:
- Hal Finkel <hfinkel@…> (09/25/17 16:15:39)
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
GenericIO.cxx
r14e73bb r5d57155 322 322 endian_specific_value<uint64_t, IsBigEndian> Flags; 323 323 endian_specific_value<uint64_t, IsBigEndian> Size; 324 endian_specific_value<uint64_t, IsBigEndian> ElementSize; 324 325 }; 325 326 … … 583 584 VH->Flags = VFlags; 584 585 RecordSize += VH->Size = Vars[i].Size; 586 VH->ElementSize = Vars[i].ElementSize; 585 587 } 586 588 … … 1379 1381 } 1380 1382 1383 size_t ElementSize = VH->Size; 1384 if (offsetof_safe(VH, ElementSize) < GH->VarsSize) 1385 ElementSize = VH->ElementSize; 1386 1381 1387 VarFound = true; 1382 1388 bool IsFloat = (bool) (VH->Flags & FloatValue), … … 1387 1393 " in: " << OpenFileName << ": current: " << Vars[i].Size << 1388 1394 ", file: " << VH->Size; 1395 throw runtime_error(ss.str()); 1396 } else if (ElementSize != Vars[i].ElementSize) { 1397 stringstream ss; 1398 ss << "Element size mismatch for variable " << Vars[i].Name << 1399 " in: " << OpenFileName << ": current: " << Vars[i].ElementSize << 1400 ", file: " << ElementSize; 1389 1401 throw runtime_error(ss.str()); 1390 1402 } else if (IsFloat != Vars[i].IsFloat) { … … 1565 1577 // Byte swap the data if necessary. 1566 1578 if (IsBigEndian != isBigEndian()) 1567 for (size_t j = 0; j < RH->NElems; ++j) { 1568 char *Offset = ((char *) VarData) + j*Vars[i].Size; 1569 bswap(Offset, Vars[i].Size); 1579 for (size_t j = 0; 1580 j < RH->NElems*(Vars[i].Size/Vars[i].ElementSize); ++j) { 1581 char *Offset = ((char *) VarData) + j*Vars[i].ElementSize; 1582 bswap(Offset, Vars[i].ElementSize); 1570 1583 } 1571 1584 … … 1625 1638 if (VNameNull < NameSize) 1626 1639 VName.resize(VNameNull); 1640 1641 size_t ElementSize = VH->Size; 1642 if (offsetof_safe(VH, ElementSize) < GH->VarsSize) 1643 ElementSize = VH->ElementSize; 1627 1644 1628 1645 bool IsFloat = (bool) (VH->Flags & FloatValue), … … 1634 1651 VI.push_back(VariableInfo(VName, (size_t) VH->Size, IsFloat, IsSigned, 1635 1652 IsPhysCoordX, IsPhysCoordY, IsPhysCoordZ, 1636 MaybePhysGhost ));1653 MaybePhysGhost, ElementSize)); 1637 1654 } 1638 1655 } -
GenericIO.h
r14e73bb r5d57155 117 117 int FH; 118 118 }; 119 120 namespace detail { 121 // A standard enable_if idiom (we include our own here for pre-C++11 support). 122 template <bool B, typename T = void> 123 struct enable_if {}; 124 125 template <typename T> 126 struct enable_if<true, T> { typedef T type; }; 127 128 // A SFINAE-based trait to detect whether a type has a member named x. This is 129 // designed to work both with structs/classes and also with OpenCL-style vector 130 // types. 131 template <typename T> 132 class has_x { 133 typedef char yes[1]; 134 typedef char no[2]; 135 136 template <typename C> 137 static yes &test(char(*)[sizeof((*((C *) 0)).x)]); 138 139 template <typename C> 140 static no &test(...); 141 142 public: 143 enum { value = sizeof(test<T>(0)) == sizeof(yes) }; 144 }; 145 146 // A SFINAE-based trait to detect whether a type is array-like (i.e. supports 147 // the [] operator). 148 template <typename T> 149 class is_array { 150 typedef char yes[1]; 151 typedef char no[2]; 152 153 template <typename C> 154 static yes &test(char(*)[sizeof((*((C *) 0))[0])]); 155 156 template <typename C> 157 static no &test(...); 158 159 public: 160 enum { value = sizeof(test<T>(0)) == sizeof(yes) }; 161 }; 162 } // namespace detail 119 163 120 164 class GenericIO { … … 133 177 struct VariableInfo { 134 178 VariableInfo(const std::string &N, std::size_t S, bool IF, bool IS, 135 bool PCX, bool PCY, bool PCZ, bool PG )179 bool PCX, bool PCY, bool PCZ, bool PG, std::size_t ES = 0) 136 180 : Name(N), Size(S), IsFloat(IF), IsSigned(IS), 137 181 IsPhysCoordX(PCX), IsPhysCoordY(PCY), IsPhysCoordZ(PCZ), 138 MaybePhysGhost(PG) {}182 MaybePhysGhost(PG), ElementSize(ES ? ES : S) {} 139 183 140 184 std::string Name; … … 144 188 bool IsPhysCoordX, IsPhysCoordY, IsPhysCoordZ; 145 189 bool MaybePhysGhost; 190 std::size_t ElementSize; 146 191 }; 147 192 148 193 public: 149 struct Variable { 194 class Variable { 195 private: 196 template <typename ET> 197 void deduceTypeInfoFromElement(ET *) { 198 ElementSize = sizeof(ET); 199 IsFloat = !std::numeric_limits<ET>::is_integer; 200 IsSigned = std::numeric_limits<ET>::is_signed; 201 } 202 203 // There are specializations here to handle array types 204 // (e.g. typedef float float4[4];), struct types 205 // (e.g. struct float4 { float x, y, z, w; };), and scalar types. 206 // Builtin vector types 207 // (e.g. typedef float float4 __attribute__((ext_vector_type(4)));) should 208 // also work. 209 template <typename T> 210 typename detail::enable_if<detail::is_array<T>::value, void>::type 211 deduceTypeInfo(T *D) { 212 Size = sizeof(T); 213 deduceTypeInfoFromElement(&(*D)[0]); 214 } 215 216 template <typename T> 217 typename detail::enable_if<detail::has_x<T>::value && 218 !detail::is_array<T>::value, void>::type 219 deduceTypeInfo(T *D) { 220 Size = sizeof(T); 221 deduceTypeInfoFromElement(&(*D).x); 222 } 223 224 template <typename T> 225 typename detail::enable_if<!detail::has_x<T>::value && 226 !detail::is_array<T>::value, void>::type 227 deduceTypeInfo(T *D) { 228 Size = sizeof(T); 229 deduceTypeInfoFromElement(D); 230 } 231 232 public: 150 233 template <typename T> 151 234 Variable(const std::string &N, T* D, unsigned Flags = 0) 152 : Name(N), Size(sizeof(T)), 153 IsFloat(!std::numeric_limits<T>::is_integer), 154 IsSigned(std::numeric_limits<T>::is_signed), 155 Data((void *) D), HasExtraSpace(Flags & VarHasExtraSpace), 235 : Name(N), Data((void *) D), HasExtraSpace(Flags & VarHasExtraSpace), 156 236 IsPhysCoordX(Flags & VarIsPhysCoordX), 157 237 IsPhysCoordY(Flags & VarIsPhysCoordY), 158 238 IsPhysCoordZ(Flags & VarIsPhysCoordZ), 159 MaybePhysGhost(Flags & VarMaybePhysGhost) {} 239 MaybePhysGhost(Flags & VarMaybePhysGhost) { 240 deduceTypeInfo(D); 241 } 242 243 template <typename T> 244 Variable(const std::string &N, std::size_t NumElements, T* D, 245 unsigned Flags = 0) 246 : Name(N), Data((void *) D), HasExtraSpace(Flags & VarHasExtraSpace), 247 IsPhysCoordX(Flags & VarIsPhysCoordX), 248 IsPhysCoordY(Flags & VarIsPhysCoordY), 249 IsPhysCoordZ(Flags & VarIsPhysCoordZ), 250 MaybePhysGhost(Flags & VarMaybePhysGhost) { 251 deduceTypeInfoFromElement(D); 252 Size = ElementSize*NumElements; 253 } 160 254 161 255 Variable(const VariableInfo &VI, void *D, unsigned Flags = 0) … … 166 260 IsPhysCoordY((Flags & VarIsPhysCoordY) || VI.IsPhysCoordY), 167 261 IsPhysCoordZ((Flags & VarIsPhysCoordZ) || VI.IsPhysCoordZ), 168 MaybePhysGhost((Flags & VarMaybePhysGhost) || VI.MaybePhysGhost) {} 262 MaybePhysGhost((Flags & VarMaybePhysGhost) || VI.MaybePhysGhost), 263 ElementSize(VI.ElementSize) {} 169 264 170 265 std::string Name; … … 176 271 bool IsPhysCoordX, IsPhysCoordY, IsPhysCoordZ; 177 272 bool MaybePhysGhost; 273 std::size_t ElementSize; 178 274 }; 179 275 … … 261 357 } 262 358 359 template <typename T> 360 void addScalarizedVariable(const std::string &Name, T *Data, 361 std::size_t NumElements, unsigned Flags = 0) { 362 Vars.push_back(Variable(Name, NumElements, Data, Flags)); 363 } 364 365 template <typename T, typename A> 366 void addScalarizedVariable(const std::string &Name, std::vector<T, A> &Data, 367 std::size_t NumElements, unsigned Flags = 0) { 368 T *D = Data.empty() ? 0 : &Data[0]; 369 addScalarizedVariable(Name, D, NumElements, Flags); 370 } 371 263 372 #ifndef GENERICIO_NO_MPI 264 373 // Writing -
GenericIOBenchmarkRead.cxx
r8f0a211 r5d57155 54 54 #define MASK_T uint16_t 55 55 56 struct pos_t { 57 POSVEL_T x, y, z, w; 58 }; 59 56 60 using namespace std; 57 61 using namespace gio; … … 64 68 MPI_Comm_size(MPI_COMM_WORLD, &commRanks); 65 69 70 bool UseAOS = false; 71 int a = 1; 72 if (argc > 1 && string(argv[a]) == "-a") { 73 UseAOS = true; 74 --argc; 75 ++a; 76 } 77 66 78 if(argc != 2) { 67 fprintf(stderr,"USAGE: %s <mpiioName>\n", argv[0]);79 fprintf(stderr,"USAGE: %s [-a] <mpiioName>\n", argv[0]); 68 80 exit(-1); 69 81 } 70 82 71 char *mpiioName = argv[ 1];83 char *mpiioName = argv[a]; 72 84 73 85 vector<POSVEL_T> xx, yy, zz, vx, vy, vz, phi; 74 86 vector<ID_T> id; 75 87 vector<MASK_T> mask; 88 89 vector<pos_t> pos, vel; 76 90 77 91 assert(sizeof(ID_T) == 8); … … 93 107 Np = GIO.readNumElems(); 94 108 95 xx.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 96 yy.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 97 zz.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 98 vx.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 99 vy.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 100 vz.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 101 phi.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 109 if (UseAOS) { 110 pos.resize(Np + (GIO.requestedExtraSpace() + sizeof(pos_t) - 1)/sizeof(pos_t)); 111 vel.resize(Np + (GIO.requestedExtraSpace() + sizeof(pos_t) - 1)/sizeof(pos_t)); 112 } else { 113 xx.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 114 yy.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 115 zz.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 116 vx.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 117 vy.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 118 vz.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 119 phi.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 120 } 102 121 id.resize(Np + GIO.requestedExtraSpace()/sizeof(ID_T)); 103 122 mask.resize(Np + GIO.requestedExtraSpace()/sizeof(MASK_T)); 104 123 105 GIO.addVariable("x", xx, true); 106 GIO.addVariable("y", yy, true); 107 GIO.addVariable("z", zz, true); 108 GIO.addVariable("vx", vx, true); 109 GIO.addVariable("vy", vy, true); 110 GIO.addVariable("vz", vz, true); 111 GIO.addVariable("phi", phi, true); 112 GIO.addVariable("id", id, true); 113 GIO.addVariable("mask", mask, true); 124 if (UseAOS) { 125 GIO.addVariable("pos", pos, GenericIO::VarHasExtraSpace); 126 GIO.addVariable("vel", vel, GenericIO::VarHasExtraSpace); 127 } else { 128 GIO.addVariable("x", xx, GenericIO::VarHasExtraSpace); 129 GIO.addVariable("y", yy, GenericIO::VarHasExtraSpace); 130 GIO.addVariable("z", zz, GenericIO::VarHasExtraSpace); 131 GIO.addVariable("vx", vx, GenericIO::VarHasExtraSpace); 132 GIO.addVariable("vy", vy, GenericIO::VarHasExtraSpace); 133 GIO.addVariable("vz", vz, GenericIO::VarHasExtraSpace); 134 GIO.addVariable("phi", phi, GenericIO::VarHasExtraSpace); 135 } 136 GIO.addVariable("id", id, GenericIO::VarHasExtraSpace); 137 GIO.addVariable("mask", mask, GenericIO::VarHasExtraSpace); 114 138 115 139 GIO.readData(); 116 140 } // destroy GIO prior to calling MPI_Finalize 117 141 118 xx.resize(Np); 119 yy.resize(Np); 120 zz.resize(Np); 121 vx.resize(Np); 122 vy.resize(Np); 123 vz.resize(Np); 124 phi.resize(Np); 142 if (UseAOS) { 143 pos.resize(Np); 144 vel.resize(Np); 145 } else { 146 xx.resize(Np); 147 yy.resize(Np); 148 zz.resize(Np); 149 vx.resize(Np); 150 vy.resize(Np); 151 vz.resize(Np); 152 phi.resize(Np); 153 } 125 154 id.resize(Np); 126 155 mask.resize(Np); -
GenericIOBenchmarkWrite.cxx
rcda87e9 r5d57155 70 70 }; 71 71 72 struct pos_t { 73 POSVEL_T x, y, z, w; 74 }; 75 76 template <> 77 struct Generator<pos_t> { 78 Generator(POSVEL_T start, POSVEL_T inc) : 79 GenX(start, inc), GenY(start, inc), GenZ(start, inc), GenW(start, inc) {} 80 81 pos_t operator()() { 82 pos_t v; 83 v.x = GenX(); 84 v.y = GenY(); 85 v.z = GenZ(); 86 v.w = GenW(); 87 88 return v; 89 } 90 91 Generator<POSVEL_T> GenX, GenY, GenZ, GenW; 92 }; 93 72 94 int main(int argc, char *argv[]) { 73 95 MPI_Init(&argc, &argv); … … 77 99 MPI_Comm_size(MPI_COMM_WORLD, &commRanks); 78 100 101 bool UseAOS = false; 79 102 int a = 1; 103 if (argc > 1 && string(argv[a]) == "-a") { 104 UseAOS = true; 105 --argc; 106 ++a; 107 } 108 80 109 if (argc > 1 && string(argv[a]) == "-c") { 81 110 GenericIO::setDefaultShouldCompress(true); … … 85 114 86 115 if(argc != 4) { 87 fprintf(stderr,"USAGE: %s [- c] <mpiioName> <NP> <seed>\n", argv[0]);116 fprintf(stderr,"USAGE: %s [-a] [-c] <mpiioName> <NP> <seed>\n", argv[0]); 88 117 exit(-1); 89 118 } … … 103 132 vector<ID_T> id; 104 133 vector<MASK_T> mask; 134 135 vector<pos_t> pos, vel; 105 136 106 137 assert(sizeof(ID_T) == 8); … … 123 154 GIO.setPhysScale(256.0); 124 155 125 xx.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 126 yy.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 127 zz.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 128 vx.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 129 vy.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 130 vz.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 131 phi.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 156 if (UseAOS) { 157 pos.resize(Np + (GIO.requestedExtraSpace() + sizeof(pos_t) - 1)/sizeof(pos_t)); 158 vel.resize(Np + (GIO.requestedExtraSpace() + sizeof(pos_t) - 1)/sizeof(pos_t)); 159 } else { 160 xx.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 161 yy.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 162 zz.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 163 vx.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 164 vy.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 165 vz.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 166 phi.resize(Np + GIO.requestedExtraSpace()/sizeof(POSVEL_T)); 167 } 132 168 id.resize(Np + GIO.requestedExtraSpace()/sizeof(ID_T)); 133 169 mask.resize(Np + GIO.requestedExtraSpace()/sizeof(MASK_T)); 134 170 135 std::generate(xx.begin(), xx.end(), Generator<POSVEL_T>(25, 3)); 136 std::generate(yy.begin(), yy.end(), Generator<POSVEL_T>(25, 3)); 137 std::generate(zz.begin(), zz.end(), Generator<POSVEL_T>(25, 3)); 138 std::generate(vx.begin(), vx.end(), Generator<POSVEL_T>(25, 3)); 139 std::generate(vy.begin(), vy.end(), Generator<POSVEL_T>(25, 3)); 140 std::generate(vz.begin(), vz.end(), Generator<POSVEL_T>(25, 3)); 141 std::generate(phi.begin(), phi.end(), Generator<POSVEL_T>(25, 3)); 171 if (UseAOS) { 172 std::generate(pos.begin(), pos.end(), Generator<pos_t>(25, 3)); 173 std::generate(vel.begin(), vel.end(), Generator<pos_t>(25, 3)); 174 } else { 175 std::generate(xx.begin(), xx.end(), Generator<POSVEL_T>(25, 3)); 176 std::generate(yy.begin(), yy.end(), Generator<POSVEL_T>(25, 3)); 177 std::generate(zz.begin(), zz.end(), Generator<POSVEL_T>(25, 3)); 178 std::generate(vx.begin(), vx.end(), Generator<POSVEL_T>(25, 3)); 179 std::generate(vy.begin(), vy.end(), Generator<POSVEL_T>(25, 3)); 180 std::generate(vz.begin(), vz.end(), Generator<POSVEL_T>(25, 3)); 181 std::generate(phi.begin(), phi.end(), Generator<POSVEL_T>(25, 3)); 182 } 142 183 std::generate(id.begin(), id.end(), Generator<ID_T>(25, 3)); 143 184 std::fill(mask.begin(), mask.end(), 25); 144 185 145 GIO.addVariable("x", xx, CoordFlagsX | GenericIO::VarHasExtraSpace); 146 GIO.addVariable("y", yy, CoordFlagsY | GenericIO::VarHasExtraSpace); 147 GIO.addVariable("z", zz, CoordFlagsZ | GenericIO::VarHasExtraSpace); 148 GIO.addVariable("vx", vx, GenericIO::VarHasExtraSpace); 149 GIO.addVariable("vy", vy, GenericIO::VarHasExtraSpace); 150 GIO.addVariable("vz", vz, GenericIO::VarHasExtraSpace); 151 GIO.addVariable("phi", phi, GenericIO::VarHasExtraSpace); 186 if (UseAOS) { 187 GIO.addVariable("pos", pos, CoordFlagsX | CoordFlagsY | CoordFlagsZ | 188 GenericIO::VarHasExtraSpace); 189 GIO.addVariable("vel", vel, GenericIO::VarHasExtraSpace); 190 } else { 191 GIO.addVariable("x", xx, CoordFlagsX | GenericIO::VarHasExtraSpace); 192 GIO.addVariable("y", yy, CoordFlagsY | GenericIO::VarHasExtraSpace); 193 GIO.addVariable("z", zz, CoordFlagsZ | GenericIO::VarHasExtraSpace); 194 GIO.addVariable("vx", vx, GenericIO::VarHasExtraSpace); 195 GIO.addVariable("vy", vy, GenericIO::VarHasExtraSpace); 196 GIO.addVariable("vz", vz, GenericIO::VarHasExtraSpace); 197 GIO.addVariable("phi", phi, GenericIO::VarHasExtraSpace); 198 } 152 199 GIO.addVariable("id", id, GenericIO::VarHasExtraSpace); 153 200 GIO.addVariable("mask", mask, GenericIO::VarHasExtraSpace); … … 156 203 } // destroy GIO prior to calling MPI_Finalize 157 204 158 xx.resize(Np); 159 yy.resize(Np); 160 zz.resize(Np); 161 vx.resize(Np); 162 vy.resize(Np); 163 vz.resize(Np); 164 phi.resize(Np); 205 if (UseAOS) { 206 pos.resize(Np); 207 vel.resize(Np); 208 } else { 209 xx.resize(Np); 210 yy.resize(Np); 211 zz.resize(Np); 212 vx.resize(Np); 213 vy.resize(Np); 214 vz.resize(Np); 215 phi.resize(Np); 216 } 165 217 id.resize(Np); 166 218 mask.resize(Np); -
GenericIOPrint.cxx
r8f0a211 r5d57155 63 63 class Printer : public PrinterBase { 64 64 public: 65 Printer(GenericIO &G, size_t MNE, const string &N)66 : Data(MNE + G.requestedExtraSpace()/sizeof(T)) {67 G.add Variable(N, Data, true);65 Printer(GenericIO &G, size_t MNE, size_t NE, const string &N) 66 : NumElements(NE), Data(MNE*NE + G.requestedExtraSpace()/sizeof(T)) { 67 G.addScalarizedVariable(N, Data, NE, GenericIO::VarHasExtraSpace); 68 68 } 69 69 70 70 virtual void print(ostream &os, size_t i) { 71 os << scientific << setprecision(numeric_limits<T>::digits10) << Data[i]; 71 for (size_t j = 0; j < NumElements; ++j) { 72 os << scientific << setprecision(numeric_limits<T>::digits10) << 73 Data[i*NumElements + j]; 74 75 if (j != NumElements - 1) 76 os << "\t"; 77 } 72 78 } 73 79 74 80 protected: 81 size_t NumElements; 75 82 vector<T> Data; 76 83 }; … … 79 86 PrinterBase *addPrinter(GenericIO::VariableInfo &V, 80 87 GenericIO &GIO, size_t MNE) { 81 if (sizeof(T) != V. Size)88 if (sizeof(T) != V.ElementSize) 82 89 return 0; 83 90 … … 87 94 return 0; 88 95 89 return new Printer<T>(GIO, MNE, V. Name);96 return new Printer<T>(GIO, MNE, V.Size/V.ElementSize, V.Name); 90 97 } 91 98 … … 241 248 cout << "# "; 242 249 for (size_t i = 0; i < VI.size(); ++i) { 243 cout << VI[i].Name; 250 if (VI[i].Size == VI[i].ElementSize) { 251 cout << VI[i].Name; 252 } else { 253 size_t NumElements = VI[i].Size/VI[i].ElementSize; 254 for (size_t j = 0; j < NumElements; ++j) { 255 cout << VI[i].Name; 256 if (j == 0) { 257 cout << ".x"; 258 } else if (j == 1) { 259 cout << ".y"; 260 } else if (j == 2) { 261 cout << ".z"; 262 } else if (j == 3) { 263 cout << ".w"; 264 } else { 265 cout << ".w" << (j - 3); 266 } 267 268 if (j != NumElements - 1) 269 cout << "\t"; 270 } 271 } 272 244 273 if (i != VI.size() - 1) 245 274 cout << "\t";
Note: See TracChangeset
for help on using the changeset viewer.