<commit_before>/* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license.
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "./hash_set_wrap.h"

namespace HashSetWrap {

using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::Persistent;
using v8::String;
using v8::Boolean;
using v8::Value;
using v8::NewStringType;

#if V8_MAJOR_VERSION >= 7
#define CHECK_SET(X) X.Check()
#else
#define CHECK_SET(X) (void)X
#endif

Persistent<Function> HashSetWrap::constructor;

HashSetWrap::HashSetWrap(uint32_t bucket_count, bool multi_set)
  : HashSet(bucket_count, multi_set) {
}

HashSetWrap::~HashSetWrap() {
}

void HashSetWrap::Init(Local<Object> exports) {
  Isolate* isolate = exports->GetIsolate();

  // Prepare constructor template
  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);
  //tpl->SetClassName(String::NewFromUtf8(isolate, "HashSet"));
  tpl->SetClassName(String::NewFromUtf8(isolate, "HashSet", NewStringType::kNormal).ToLocalChecked());
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  // Prototype
  NODE_SET_PROTOTYPE_METHOD(tpl, "add", HashSetWrap::AddItem);
  NODE_SET_PROTOTYPE_METHOD(tpl, "exists", HashSetWrap::ItemExists);

  constructor.Reset(isolate,
    tpl->GetFunction(isolate->GetCurrentContext()).ToLocalChecked());
  CHECK_SET(exports->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "HashSetecp", NewStringType::kNormal).ToLocalChecked(),
  tpl->GetFunction(isolate->GetCurrentContext()).ToLocalChecked()));
  // exports->Set(String::NewFromUtf8(isolate, "HashSet"),
  //   tpl->GetFunction(isolate->GetCurrentContext()).ToLocalChecked());
}

void HashSetWrap::New(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  if (args.IsConstructCall()) {
    // Invoked as constructor: `new HashSet(...)`
    HashSetWrap* obj = new HashSetWrap(1024, false);
    obj->Wrap(args.This());
    args.GetReturnValue().Set(args.This());
  } else {
    // Invoked as plain function `HashSet(...)`, turn into construct call.
    const int argc = 1;
    Local<Value> argv[argc] = { args[0] };
    Local<Function> cons = Local<Function>::New(isolate, constructor);
    args.GetReturnValue().Set(
      cons->NewInstance(isolate->GetCurrentContext(), argc, argv)
        .ToLocalChecked());
  }
}

void HashSetWrap::AddItem(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  String::Utf8Value str(isolate,
    args[0]->ToString(isolate->GetCurrentContext())
      .FromMaybe(v8::Local<v8::String>()));
  const char * buffer = *str;

  HashSetWrap* obj = ObjectWrap::Unwrap<HashSetWrap>(args.Holder());
  obj->Add(ExampleData(buffer));
}

void HashSetWrap::ItemExists(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  String::Utf8Value str(isolate,
    args[0]->ToString(isolate->GetCurrentContext())
      .FromMaybe(v8::Local<v8::String>()));
  const char * buffer = *str;

  HashSetWrap* obj = ObjectWrap::Unwrap<HashSetWrap>(args.Holder());
  bool exists = obj->Exists(ExampleData(buffer));

  args.GetReturnValue().Set(Boolean::New(isolate, exists));
}

}  // namespace HashSetWrap
<commit_msg>cleanup<commit_after>/* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license.
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "./hash_set_wrap.h"

namespace HashSetWrap {

using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::Persistent;
using v8::String;
using v8::Boolean;
using v8::Value;
using v8::NewStringType;

#if V8_MAJOR_VERSION >= 7
#define CHECK_SET(X) X.Check()
#else
#define CHECK_SET(X) (void)X
#endif

Persistent<Function> HashSetWrap::constructor;

HashSetWrap::HashSetWrap(uint32_t bucket_count, bool multi_set)
  : HashSet(bucket_count, multi_set) {
}

HashSetWrap::~HashSetWrap() {
}

void HashSetWrap::Init(Local<Object> exports) {
  Isolate* isolate = exports->GetIsolate();

  // Prepare constructor template
  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);
  tpl->SetClassName(String::NewFromUtf8(isolate, "HashSet", NewStringType::kNormal).ToLocalChecked());
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  // Prototype
  NODE_SET_PROTOTYPE_METHOD(tpl, "add", HashSetWrap::AddItem);
  NODE_SET_PROTOTYPE_METHOD(tpl, "exists", HashSetWrap::ItemExists);

  constructor.Reset(isolate,
    tpl->GetFunction(isolate->GetCurrentContext()).ToLocalChecked());
  CHECK_SET(exports->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "HashSetecp", NewStringType::kNormal).ToLocalChecked(),
  tpl->GetFunction(isolate->GetCurrentContext()).ToLocalChecked()));
}

void HashSetWrap::New(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  if (args.IsConstructCall()) {
    // Invoked as constructor: `new HashSet(...)`
    HashSetWrap* obj = new HashSetWrap(1024, false);
    obj->Wrap(args.This());
    args.GetReturnValue().Set(args.This());
  } else {
    // Invoked as plain function `HashSet(...)`, turn into construct call.
    const int argc = 1;
    Local<Value> argv[argc] = { args[0] };
    Local<Function> cons = Local<Function>::New(isolate, constructor);
    args.GetReturnValue().Set(
      cons->NewInstance(isolate->GetCurrentContext(), argc, argv)
        .ToLocalChecked());
  }
}

void HashSetWrap::AddItem(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  String::Utf8Value str(isolate,
    args[0]->ToString(isolate->GetCurrentContext())
      .FromMaybe(v8::Local<v8::String>()));
  const char * buffer = *str;

  HashSetWrap* obj = ObjectWrap::Unwrap<HashSetWrap>(args.Holder());
  obj->Add(ExampleData(buffer));
}

void HashSetWrap::ItemExists(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  String::Utf8Value str(isolate,
    args[0]->ToString(isolate->GetCurrentContext())
      .FromMaybe(v8::Local<v8::String>()));
  const char * buffer = *str;

  HashSetWrap* obj = ObjectWrap::Unwrap<HashSetWrap>(args.Holder());
  bool exists = obj->Exists(ExampleData(buffer));

  args.GetReturnValue().Set(Boolean::New(isolate, exists));
}

}  // namespace HashSetWrap
<|endoftext|>


<commit_before>/* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license.
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "./hash_set_wrap.h"

namespace HashSetWrap {

using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::Persistent;
using v8::String;
using v8::Boolean;
using v8::Value;

Persistent<Function> HashSetWrap::constructor;

HashSetWrap::HashSetWrap(uint32_t bucket_count, bool multi_set)
  : HashSet(bucket_count, multi_set) {
}

HashSetWrap::~HashSetWrap() {
}

void HashSetWrap::Init(Local<Object> exports) {
  Isolate* isolate = exports->GetIsolate();

  // Prepare constructor template
  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);
  tpl->SetClassName(String::NewFromUtf8(isolate, "HashSet"));
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  // Prototype
  NODE_SET_PROTOTYPE_METHOD(tpl, "add", HashSetWrap::AddItem);
  NODE_SET_PROTOTYPE_METHOD(tpl, "exists", HashSetWrap::ItemExists);

  constructor.Reset(isolate,
    tpl->GetFunction(isolate->GetCurrentContext()).ToLocalChecked());
  exports->Set(String::NewFromUtf8(isolate, "HashSet"),
    tpl->GetFunction(isolate->GetCurrentContext()).ToLocalChecked());
}

void HashSetWrap::New(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  if (args.IsConstructCall()) {
    // Invoked as constructor: `new HashSet(...)`
    HashSetWrap* obj = new HashSetWrap(1024, false);
    obj->Wrap(args.This());
    args.GetReturnValue().Set(args.This());
  } else {
    // Invoked as plain function `HashSet(...)`, turn into construct call.
    const int argc = 1;
    Local<Value> argv[argc] = { args[0] };
    Local<Function> cons = Local<Function>::New(isolate, constructor);
    args.GetReturnValue().Set(
      cons->NewInstance(isolate->GetCurrentContext(), argc, argv)
        .ToLocalChecked());
  }
}

void HashSetWrap::AddItem(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  String::Utf8Value str(isolate,
    args[0]->ToString(isolate->GetCurrentContext())
      .FromMaybe(v8::Local<v8::String>()));
  const char * buffer = *str;

  HashSetWrap* obj = ObjectWrap::Unwrap<HashSetWrap>(args.Holder());
  obj->Add(ExampleData(buffer));
}

void HashSetWrap::ItemExists(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  String::Utf8Value str(isolate,
    args[0]->ToString(isolate->GetCurrentContext())
      .FromMaybe(v8::Local<v8::String>()));
  const char * buffer = *str;

  HashSetWrap* obj = ObjectWrap::Unwrap<HashSetWrap>(args.Holder());
  bool exists = obj->Exists(ExampleData(buffer));

  args.GetReturnValue().Set(Boolean::New(isolate, exists));
}

}  // namespace HashSetWrap
<commit_msg>change export set<commit_after>/* Copyright (c) 2015 Brian R. Bondy. Distributed under the MPL2 license.
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "./hash_set_wrap.h"

namespace HashSetWrap {

using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::Persistent;
using v8::String;
using v8::Boolean;
using v8::Value;
using v8::NewStringType;

#if V8_MAJOR_VERSION >= 7
#define CHECK_SET(X) X.Check()
#else
#define CHECK_SET(X) (void)X
#endif

Persistent<Function> HashSetWrap::constructor;

HashSetWrap::HashSetWrap(uint32_t bucket_count, bool multi_set)
  : HashSet(bucket_count, multi_set) {
}

HashSetWrap::~HashSetWrap() {
}

void HashSetWrap::Init(Local<Object> exports) {
  Isolate* isolate = exports->GetIsolate();

  // Prepare constructor template
  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);
  tpl->SetClassName(String::NewFromUtf8(isolate, "HashSet"));
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  // Prototype
  NODE_SET_PROTOTYPE_METHOD(tpl, "add", HashSetWrap::AddItem);
  NODE_SET_PROTOTYPE_METHOD(tpl, "exists", HashSetWrap::ItemExists);

  constructor.Reset(isolate,
    tpl->GetFunction(isolate->GetCurrentContext()).ToLocalChecked());
  CHECK_SET(exports->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "HashSet", NewStringType::kNormal).ToLocalChecked(),
  tpl->GetFunction(isolate->GetCurrentContext()).ToLocalChecked()));
  // exports->Set(String::NewFromUtf8(isolate, "HashSet"),
  //   tpl->GetFunction(isolate->GetCurrentContext()).ToLocalChecked());
}

void HashSetWrap::New(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  if (args.IsConstructCall()) {
    // Invoked as constructor: `new HashSet(...)`
    HashSetWrap* obj = new HashSetWrap(1024, false);
    obj->Wrap(args.This());
    args.GetReturnValue().Set(args.This());
  } else {
    // Invoked as plain function `HashSet(...)`, turn into construct call.
    const int argc = 1;
    Local<Value> argv[argc] = { args[0] };
    Local<Function> cons = Local<Function>::New(isolate, constructor);
    args.GetReturnValue().Set(
      cons->NewInstance(isolate->GetCurrentContext(), argc, argv)
        .ToLocalChecked());
  }
}

void HashSetWrap::AddItem(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  String::Utf8Value str(isolate,
    args[0]->ToString(isolate->GetCurrentContext())
      .FromMaybe(v8::Local<v8::String>()));
  const char * buffer = *str;

  HashSetWrap* obj = ObjectWrap::Unwrap<HashSetWrap>(args.Holder());
  obj->Add(ExampleData(buffer));
}

void HashSetWrap::ItemExists(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  String::Utf8Value str(isolate,
    args[0]->ToString(isolate->GetCurrentContext())
      .FromMaybe(v8::Local<v8::String>()));
  const char * buffer = *str;

  HashSetWrap* obj = ObjectWrap::Unwrap<HashSetWrap>(args.Holder());
  bool exists = obj->Exists(ExampleData(buffer));

  args.GetReturnValue().Set(Boolean::New(isolate, exists));
}

}  // namespace HashSetWrap
<|endoftext|>


<commit_before>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * IO_ADIOS2.cpp
 *
 *  Created on: Feb 2017
 *      Author: Norbert Podhorszki
 */

#include "IO.h"

#include <string>
#include <stdexcept>
#include <hdf5.h>
#include <memory>
#include <ios>
#include <iostream>

class HDF5NativeWriter
{

public:
    HDF5NativeWriter(const std::string &fileName);
    ~HDF5NativeWriter();

    bool Advance();
    void Close();
    void CheckWriteGroup();

    void WriteScalar(const std::string &varName, const void *data,
                     hid_t h5Type);
    void WriteSimple(const std::string &varName, int dimSize, const void *data,
                     hid_t h5Type, const hsize_t *shape, const hsize_t *offset,
                     const hsize_t *count);

    int m_CurrentTimeStep;
    unsigned int m_TotalTimeSteps;

private:
    hid_t m_FilePropertyListId;
    hid_t m_FileId;
    hid_t m_GroupId;
};

HDF5NativeWriter::HDF5NativeWriter(const std::string &fileName)
: m_CurrentTimeStep(0), m_TotalTimeSteps(0)
{
    m_FilePropertyListId = H5Pcreate(H5P_FILE_ACCESS);

#ifdef ADIOS2_HAVE_MPI
    // read a file collectively
    H5Pset_fapl_mpio(m_FilePropertyListId, MPI_COMM_WORLD, MPI_INFO_NULL);
#endif

    m_FileId = H5Fcreate(fileName.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT,
                         m_FilePropertyListId);

    if (m_FileId < 0)
    {
        throw std::runtime_error("Unable to open " + fileName + " for reading");
    }

    std::string ts0 = "/TimeStep0";

    m_GroupId = H5Gcreate2(m_FileId, ts0.c_str(), H5P_DEFAULT, H5P_DEFAULT,
                           H5P_DEFAULT);
    if (m_GroupId < 0)
    {
        throw std::runtime_error("HDF5: Unable to create group " + ts0);
    }
}

HDF5NativeWriter::~HDF5NativeWriter() { Close(); }

void HDF5NativeWriter::Close()
{
    if (m_FileId < 0)
        return;

    hid_t s = H5Screate(H5S_SCALAR);
    hid_t attr = H5Acreate(m_FileId, "NumTimeSteps", H5T_NATIVE_UINT, s,
                           H5P_DEFAULT, H5P_DEFAULT);
    uint totalTimeSteps = m_CurrentTimeStep + 1;

    if (m_GroupId < 0)
    {
        totalTimeSteps = m_CurrentTimeStep;
    }
    H5Awrite(attr, H5T_NATIVE_UINT, &totalTimeSteps);
    H5Sclose(s);
    H5Aclose(attr);

    if (m_GroupId >= 0)
    {
        H5Gclose(m_GroupId);
        m_GroupId = -1;
    }

    H5Fclose(m_FileId);
    m_FileId = -1;
    H5Pclose(m_FilePropertyListId);
}

bool HDF5NativeWriter::Advance()
{
    if (m_GroupId >= 0)
    {
        H5Gclose(m_GroupId);
        m_GroupId = -1;
    }

    ++m_CurrentTimeStep;

    return true;
}

void HDF5NativeWriter::CheckWriteGroup()
{
    if (m_GroupId >= 0)
    {
        return;
    }

    std::string timeStepName = "/TimeStep" + std::to_string(m_CurrentTimeStep);
    m_GroupId = H5Gcreate2(m_FileId, timeStepName.c_str(), H5P_DEFAULT,
                           H5P_DEFAULT, H5P_DEFAULT);
    if (m_GroupId < 0)
    {
        throw std::runtime_error("HDF5: Unable to create group " +
                                 timeStepName);
    }
}

void HDF5NativeWriter::WriteScalar(const std::string &varName, const void *data,
                                   hid_t h5Type)
{
    CheckWriteGroup();
    // scalar
    hid_t filespaceID = H5Screate(H5S_SCALAR);
    hid_t dsetID = H5Dcreate(m_GroupId, varName.c_str(), h5Type, filespaceID,
                             H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    herr_t status =
        H5Dwrite(dsetID, h5Type, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);

    H5Sclose(filespaceID);
    H5Dclose(dsetID);
}

void HDF5NativeWriter::WriteSimple(const std::string &varName, int dimSize,
                                   const void *data, hid_t h5Type,
                                   const hsize_t *shape, const hsize_t *offset,
                                   const hsize_t *count)
{
    CheckWriteGroup();
    hid_t fileSpace = H5Screate_simple(dimSize, shape, NULL);

    hid_t dsetID = H5Dcreate(m_GroupId, varName.c_str(), h5Type, fileSpace,
                             H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

    hid_t memSpace = H5Screate_simple(dimSize, count, NULL);

    // Select hyperslab
    fileSpace = H5Dget_space(dsetID);
    H5Sselect_hyperslab(fileSpace, H5S_SELECT_SET, offset, NULL, count, NULL);

    //  Create property list for collective dataset write.

    hid_t plistID = H5Pcreate(H5P_DATASET_XFER);
#ifdef ADIOS2_HAVE_MPI
    H5Pset_dxpl_mpio(plistID, H5FD_MPIO_COLLECTIVE);
#endif
    herr_t status;

    status = H5Dwrite(dsetID, h5Type, memSpace, fileSpace, plistID, data);

    if (status < 0)
    {
        // error
        std::cerr << " Write failed. " << std::endl;
    }

    H5Dclose(dsetID);
    H5Sclose(fileSpace);
    H5Sclose(memSpace);
    H5Pclose(plistID);
}

//
//
std::shared_ptr<HDF5NativeWriter> h5writer;
// HDF5NativeWriter* h5writer;

IO::IO(const Settings &s, MPI_Comm comm)
{
    m_outputfilename = s.outputfile + ".h5";

    h5writer = std::make_shared<HDF5NativeWriter>(m_outputfilename);

    if (h5writer == nullptr)
        throw std::ios_base::failure("ERROR: failed to open ADIOS h5writer\n");
}

IO::~IO()
{
    h5writer->Close();
    // delete h5writer;
}

void IO::write(int step, const HeatTransfer &ht, const Settings &s,
               MPI_Comm comm)
{
    std::vector<hsize_t> dims = {s.gndx, s.gndy};
    std::vector<hsize_t> offset = {s.offsx, s.offsy};
    std::vector<hsize_t> count = {s.ndx, s.ndy};

    h5writer->WriteSimple("T", 2, ht.data_noghost().data(), H5T_NATIVE_DOUBLE,
                          dims.data(), offset.data(), count.data());
    h5writer->WriteScalar("gndy", &(s.gndy), H5T_NATIVE_UINT);

    h5writer->Advance();
}
<commit_msg>minor change<commit_after>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * IO_ADIOS2.cpp
 *
 *  Created on: Feb 2017
 *      Author: Norbert Podhorszki
 */

#include "IO.h"

#include <string>
#include <stdexcept>
#include <hdf5.h>
#include <memory>
#include <ios>
#include <iostream>

class HDF5NativeWriter
{

public:
    HDF5NativeWriter(const std::string &fileName);
    ~HDF5NativeWriter();

    bool Advance();
    void Close();
    void CheckWriteGroup();

    void WriteScalar(const std::string &varName, const void *data,
                     hid_t h5Type);
    void WriteSimple(const std::string &varName, int dimSize, const void *data,
                     hid_t h5Type, const hsize_t *shape, const hsize_t *offset,
                     const hsize_t *count);

    int m_CurrentTimeStep;
    unsigned int m_TotalTimeSteps;

private:
    hid_t m_FilePropertyListId;
    hid_t m_FileId;
    hid_t m_GroupId;
};

HDF5NativeWriter::HDF5NativeWriter(const std::string &fileName)
: m_CurrentTimeStep(0), m_TotalTimeSteps(0)
{
    m_FilePropertyListId = H5Pcreate(H5P_FILE_ACCESS);

    // read a file collectively
    H5Pset_fapl_mpio(m_FilePropertyListId, MPI_COMM_WORLD, MPI_INFO_NULL);

    m_FileId = H5Fcreate(fileName.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT,
                         m_FilePropertyListId);

    if (m_FileId < 0)
    {
        throw std::runtime_error("Unable to open " + fileName + " for reading");
    }

    std::string ts0 = "/TimeStep0";

    m_GroupId = H5Gcreate2(m_FileId, ts0.c_str(), H5P_DEFAULT, H5P_DEFAULT,
                           H5P_DEFAULT);
    if (m_GroupId < 0)
    {
        throw std::runtime_error("HDF5: Unable to create group " + ts0);
    }
}

HDF5NativeWriter::~HDF5NativeWriter() { Close(); }

void HDF5NativeWriter::Close()
{
    if (m_FileId < 0)
        return;

    hid_t s = H5Screate(H5S_SCALAR);
    hid_t attr = H5Acreate(m_FileId, "NumTimeSteps", H5T_NATIVE_UINT, s,
                           H5P_DEFAULT, H5P_DEFAULT);
    uint totalTimeSteps = m_CurrentTimeStep + 1;

    if (m_GroupId < 0)
    {
        totalTimeSteps = m_CurrentTimeStep;
    }
    H5Awrite(attr, H5T_NATIVE_UINT, &totalTimeSteps);
    H5Sclose(s);
    H5Aclose(attr);

    if (m_GroupId >= 0)
    {
        H5Gclose(m_GroupId);
        m_GroupId = -1;
    }

    H5Fclose(m_FileId);
    m_FileId = -1;
    H5Pclose(m_FilePropertyListId);
}

bool HDF5NativeWriter::Advance()
{
    if (m_GroupId >= 0)
    {
        H5Gclose(m_GroupId);
        m_GroupId = -1;
    }

    ++m_CurrentTimeStep;

    return true;
}

void HDF5NativeWriter::CheckWriteGroup()
{
    if (m_GroupId >= 0)
    {
        return;
    }

    std::string timeStepName = "/TimeStep" + std::to_string(m_CurrentTimeStep);
    m_GroupId = H5Gcreate2(m_FileId, timeStepName.c_str(), H5P_DEFAULT,
                           H5P_DEFAULT, H5P_DEFAULT);
    if (m_GroupId < 0)
    {
        throw std::runtime_error("HDF5: Unable to create group " +
                                 timeStepName);
    }
}

void HDF5NativeWriter::WriteScalar(const std::string &varName, const void *data,
                                   hid_t h5Type)
{
    CheckWriteGroup();
    // scalar
    hid_t filespaceID = H5Screate(H5S_SCALAR);
    hid_t dsetID = H5Dcreate(m_GroupId, varName.c_str(), h5Type, filespaceID,
                             H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    herr_t status =
        H5Dwrite(dsetID, h5Type, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);

    H5Sclose(filespaceID);
    H5Dclose(dsetID);
}

void HDF5NativeWriter::WriteSimple(const std::string &varName, int dimSize,
                                   const void *data, hid_t h5Type,
                                   const hsize_t *shape, const hsize_t *offset,
                                   const hsize_t *count)
{
    CheckWriteGroup();
    hid_t fileSpace = H5Screate_simple(dimSize, shape, NULL);

    hid_t dsetID = H5Dcreate(m_GroupId, varName.c_str(), h5Type, fileSpace,
                             H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

    hid_t memSpace = H5Screate_simple(dimSize, count, NULL);

    // Select hyperslab
    fileSpace = H5Dget_space(dsetID);
    H5Sselect_hyperslab(fileSpace, H5S_SELECT_SET, offset, NULL, count, NULL);

    //  Create property list for collective dataset write.

    hid_t plistID = H5Pcreate(H5P_DATASET_XFER);
    H5Pset_dxpl_mpio(plistID, H5FD_MPIO_COLLECTIVE);

    herr_t status;

    status = H5Dwrite(dsetID, h5Type, memSpace, fileSpace, plistID, data);

    if (status < 0)
    {
        // error
        std::cerr << " Write failed. " << std::endl;
    }

    H5Dclose(dsetID);
    H5Sclose(fileSpace);
    H5Sclose(memSpace);
    H5Pclose(plistID);
}

//
//
std::shared_ptr<HDF5NativeWriter> h5writer;
// HDF5NativeWriter* h5writer;

IO::IO(const Settings &s, MPI_Comm comm)
{
    m_outputfilename = s.outputfile + ".h5";

    if (s.outputfile[0]=='0') {
      std::cout<<" no writer. "<<std::endl;
      h5writer = nullptr;
      return;
    }
    h5writer = std::make_shared<HDF5NativeWriter>(m_outputfilename);

    if (h5writer == nullptr)
        throw std::ios_base::failure("ERROR: failed to open ADIOS h5writer\n");
}

IO::~IO()
{
    if (h5writer != nullptr) {
      h5writer->Close();
    }
    // delete h5writer;
}

void IO::write(int step, const HeatTransfer &ht, const Settings &s,
               MPI_Comm comm)
{
    if (h5writer == nullptr) {
        return;
    }
    std::vector<hsize_t> dims = {s.gndx, s.gndy};
    std::vector<hsize_t> offset = {s.offsx, s.offsy};
    std::vector<hsize_t> count = {s.ndx, s.ndy};

    h5writer->WriteSimple("T", 2, ht.data_noghost().data(), H5T_NATIVE_DOUBLE,
                          dims.data(), offset.data(), count.data());
    h5writer->WriteScalar("gndy", &(s.gndy), H5T_NATIVE_UINT);
    h5writer->WriteScalar("gndx", &(s.gndx), H5T_NATIVE_UINT);

    h5writer->Advance();
}
<|endoftext|>


<commit_before>/*****************************************************************************\
 *                        ANALYSIS PERFORMANCE TOOLS                         *
 *                                  wxparaver                                *
 *              Paraver Trace Visualization and Analysis Tool                *
 *****************************************************************************
 *     ___     This library is free software; you can redistribute it and/or *
 *    /  __         modify it under the terms of the GNU LGPL as published   *
 *   /  /  _____    by the Free Software Foundation; either version 2.1      *
 *  /  /  /     \   of the License, or (at your option) any later version.   *
 * (  (  ( B S C )                                                           *
 *  \  \  \_____/   This library is distributed in hope that it will be      *
 *   \  \__         useful but WITHOUT ANY WARRANTY; without even the        *
 *    \___          implied warranty of MERCHANTABILITY or FITNESS FOR A     *
 *                  PARTICULAR PURPOSE. See the GNU LGPL for more details.   *
 *                                                                           *
 * You should have received a copy of the GNU Lesser General Public License  *
 * along with this library; if not, write to the Free Software Foundation,   *
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA          *
 * The GNU LEsser General Public License is contained in the file COPYING.   *
 *                                 ---------                                 *
 *   Barcelona Supercomputing Center - Centro Nacional de Supercomputacion   *
\*****************************************************************************/

/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *\
 | @file: $HeadURL$
 | @last_commit: $Date$
 | @version:     $Revision$
\* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

////@begin includes
////@end includes
#include <string>

#include "helpcontents.h"
//#include "wx/html/htmlfilt.h"

#include "paravermain.h"
////@begin XPM images
////@end XPM images

/*!
 * HelpContents type definition
 */

IMPLEMENT_DYNAMIC_CLASS( HelpContents, wxDialog )

/*!
 * HelpContents event table definition
 */

BEGIN_EVENT_TABLE( HelpContents, wxDialog )

////@begin HelpContents event table entries
  EVT_HTML_LINK_CLICKED( ID_HTMLWINDOW, HelpContents::OnHtmlwindowLinkClicked )

  EVT_BUTTON( ID_BUTTON_INDEX, HelpContents::OnButtonIndexClick )

  EVT_BUTTON( ID_BUTTON_CLOSE, HelpContents::OnButtonCloseClick )

////@end HelpContents event table entries

END_EVENT_TABLE()

/*!
 * HelpContents constructors
 */

HelpContents::HelpContents()
{
  Init();
}

HelpContents::HelpContents( wxWindow* parent,
                            wxWindowID id,
                            const wxString& caption,
                            const wxPoint& pos,
                            const wxSize& size,
                            long style )
{
  Init();
  Create(parent, id, caption, pos, size, style);
}

/*!
 * HelpContents creator
 */

bool HelpContents::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
////@begin HelpContents creation
  SetExtraStyle(wxWS_EX_BLOCK_EVENTS);
  wxDialog::Create( parent, id, caption, pos, size, style );

  CreateControls();
  if (GetSizer())
  {
    GetSizer()->SetSizeHints(this);
  }
  Centre();
////@end HelpContents creation
  return true;
}

/*!
 * HelpContents destructor
 */

HelpContents::~HelpContents()
{
}

/*!
 * Member initialisation
 */
void HelpContents::Init()
{
  currentTutorialDir = _("");
}

const wxString HelpContents::getHtmlIndex( const wxString& path )
{
  wxString htmlIndex;
  wxFileName index( path + wxFileName::GetPathSeparator() + _("index.html") );

  if ( index.FileExists() )
  {
    htmlIndex = index.GetFullPath();
  }

  return htmlIndex;
}

const wxString HelpContents::getTitle( int numTutorial, const wxString& path )
{
  wxString tutorialTitle;

  wxHtmlWindow auxHtml( this );
  auxHtml.LoadPage( path  + wxFileName::GetPathSeparator() + _("index.html") );
  tutorialTitle = auxHtml.GetOpenedPageTitle();
  if ( tutorialTitle.empty() || tutorialTitle == _("index.html") ) // never is empty !?!
  {
    string auxStrTitleFileName( path + wxFileName::GetPathSeparator() + _("tutorial_title") );
    string auxLine;

    ifstream titleFile;
    titleFile.open( auxStrTitleFileName.c_str() );
    if ( titleFile.good() )
    {
      std::getline( titleFile, auxLine );

      if ( auxLine.size() > 0 )
      {
        tutorialTitle = wxString::FromAscii( auxLine.c_str() );
      }
      else
      {
        tutorialTitle = _("Tutorial ");
        tutorialTitle << numTutorial;
      }
    }
    else
    {
      tutorialTitle = _("Tutorial ");
      tutorialTitle << numTutorial;
    }

    titleFile.close();
  }

  return tutorialTitle;
}

void HelpContents::appendTutorial( const wxString& title,
                                   const wxString& path,
                                   wxString& htmlDoc )
{
  htmlDoc += _("

") + title + _("

");
}

void HelpContents::htmlMessage( wxString& htmlDoc )
{
  htmlDoc += _("

No tutorial found!

");
/*
  htmlDoc += _("
Before going on, please have in mind that:
");
  htmlDoc += _("
");
  htmlDoc += _("
A single tutorials root directory must contain all ");
  htmlDoc += _("the tutorials directories that you want visible for wxparaver.
");
  htmlDoc += _("
In their own directories, every tutorial has a first page called <TT>index.html</TT>, and also related content (like traces, cfgs, etc.).
");
  htmlDoc += _("
You don't need to write any global tutorials page; we walk through the included tutorials ");
  htmlDoc += _("in the given root directory and build it for you.
");
  htmlDoc += _("
The tutorial title showed in this automatically built main index is read from:
");
  htmlDoc += _("
");
  htmlDoc += _("
The <TT>TITLE</TT> tag in the<TT>index.html</TT> file.
");
  htmlDoc += _("
If this tag is missing or empty, from a single line file named <TT>tutorial_title</TT>");
  htmlDoc += _(", also local to this tutorial.
");
  htmlDoc += _("
If no <TT>tutorial_title</TT> file is found, we give a numbered 'Tutorial #'.
");
  htmlDoc += _("
");
  htmlDoc += _("
");
*/
  htmlDoc += _("
Please check that root directory to tutorials is properly defined:
");
  htmlDoc += _("
");
  htmlDoc += _("
Open Preferences Window.
");
  htmlDoc += _("
Select Global tab.
");
  htmlDoc += _("
In the Default directories box, change the Tutorials root directory");
  htmlDoc += _("
The tutorials list will be immediately rebuilt after you save your ");
  htmlDoc += _("new settings clicking the Ok button in the Preferences Window.
");
  htmlDoc += _("
");
  htmlDoc += _("
If you still get this help, check these steps again, or please contact us at paraver@bsc.es.
");
}

void HelpContents::buildIndex()
{
  // get tutorials directory
  string auxStrPath = paraverMain::myParaverMain->GetParaverConfig()->getGlobalTutorialsPath();
  wxString auxPath = wxString::FromAscii( auxStrPath.c_str() );
  wxFileName tutorialsGlobalPath( auxPath );

  // open html index
  wxString tutorialsHtmlIndex, tutorialsList;
  tutorialsHtmlIndex += _("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">");
  tutorialsHtmlIndex += _("<TITLE>Tutorials</TITLE>");

  // look for tutorials directories, and for index.html inside them
  if ( wxDirExists( auxPath ) )
  {
    tutorialsList += _("
");
    int numTutorials = 0;

    wxString currentDir = wxFindFirstFile(
            tutorialsGlobalPath.GetLongPath() + wxFileName::GetPathSeparator() + _("*"),
            wxDIR );
    while( !currentDir.empty() )
    {
      wxString currentTutorialHtmlIndex( getHtmlIndex( currentDir ) );

      if ( currentTutorialHtmlIndex != _("")  )
      {
        // index.html found! => we consider this is a tutorial
        numTutorials++;

        appendTutorial( getTitle( numTutorials, currentDir ), currentTutorialHtmlIndex, tutorialsList );
      }

      currentDir = wxFindNextFile();
    }

    tutorialsList += _("
");

    if ( numTutorials == 0 )
    {
      htmlMessage( tutorialsHtmlIndex );
    }
    else
    {
      tutorialsHtmlIndex += _("

Index

");
      tutorialsHtmlIndex += tutorialsList;
    }
  }
  else
  {
    htmlMessage( tutorialsHtmlIndex );
  }

  // close html index
  tutorialsHtmlIndex += _("");

  htmlWindow->SetPage( tutorialsHtmlIndex.ToUTF8() );
}

/*!
 * Control creation for HelpContents
 */
void HelpContents::CreateControls()
{
////@begin HelpContents content construction
  HelpContents* itemDialog1 = this;

  wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
  itemDialog1->SetSizer(itemBoxSizer2);

  htmlWindow = new wxHtmlWindow( itemDialog1, ID_HTMLWINDOW, wxDefaultPosition, wxSize(600, 400), wxHW_SCROLLBAR_AUTO|wxSUNKEN_BORDER|wxHSCROLL|wxVSCROLL );
  itemBoxSizer2->Add(htmlWindow, 1, wxGROW|wxALL, 5);

  wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
  itemBoxSizer2->Add(itemBoxSizer4, 0, wxGROW|wxALL, 5);

  wxButton* itemButton5 = new wxButton( itemDialog1, ID_BUTTON_INDEX, _("Index"), wxDefaultPosition, wxDefaultSize, 0 );
  itemBoxSizer4->Add(itemButton5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

  itemBoxSizer4->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);

  wxButton* itemButton7 = new wxButton( itemDialog1, ID_BUTTON_CLOSE, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
  itemBoxSizer4->Add(itemButton7, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

////@end HelpContents content construction

  buildIndex();
}

/*!
 * Should we show tooltips?
 */

bool HelpContents::ShowToolTips()
{
  return true;
}

/*!
 * Get bitmap resources
 */

wxBitmap HelpContents::GetBitmapResource( const wxString& name )
{
  // Bitmap retrieval
////@begin HelpContents bitmap retrieval
  wxUnusedVar(name);
  return wxNullBitmap;
////@end HelpContents bitmap retrieval
}

/*!
 * Get icon resources
 */

wxIcon HelpContents::GetIconResource( const wxString& name )
{
  // Icon retrieval
////@begin HelpContents icon retrieval
  wxUnusedVar(name);
  return wxNullIcon;
////@end HelpContents icon retrieval
}

std::string HelpContents::getHrefFullPath( wxHtmlLinkEvent &event )
{
  string hrefFullPath = paraverMain::myParaverMain->GetParaverConfig()->getGlobalTutorialsPath();
  hrefFullPath += wxString( wxFileName::GetPathSeparator() ).mb_str();
  hrefFullPath += currentTutorialDir.mb_str();
  hrefFullPath += wxString( wxFileName::GetPathSeparator() ).mb_str();
  hrefFullPath += std::string( event.GetLinkInfo().GetHref().mb_str() );

  return hrefFullPath;
}

bool HelpContents::matchHrefExtension( wxHtmlLinkEvent &event, const wxString extension )
{
  return ( event.GetLinkInfo().GetHref().Right( extension.Len() ).Cmp( extension ) == 0 );
}

/*!
 * wxEVT_COMMAND_HTML_LINK_CLICKED event handler for ID_HTMLWINDOW
 */

void HelpContents::OnHtmlwindowLinkClicked( wxHtmlLinkEvent& event )
{
  if ( matchHrefExtension( event, _(".prv") ) || matchHrefExtension( event, _(".prv.gz")))
  {
    paraverMain::myParaverMain->DoLoadTrace( getHrefFullPath( event ) );
  }
  else if ( matchHrefExtension( event, _(".cfg")))
  {
    if ( paraverMain::myParaverMain->GetLoadedTraces().size() > 0 )
    {
      paraverMain::myParaverMain->DoLoadCFG( getHrefFullPath( event )  );
    }
    else
    {
      wxMessageDialog message( this, _("No trace loaded."), _( "Warning" ), wxOK );
      message.ShowModal();
    }
  }
  else if ( event.GetLinkInfo().GetHref().Cmp( _("init_preferences") ) == 0 )
  {
    paraverMain::myParaverMain->ShowPreferences();

    // we rebuild it anyway
    buildIndex();
  }
  else
  {
    // If current clicked link points to a tutorial index.html file, keep its
    //   tutorial directory name to allow relative references.
    // Idea to detect tutorial:
    //   /home/user/root-tutorials/ => dir depth tutorials = 3
    //   vs.
    //   /home/user/root-tutorials/tutorial1/index.html => dir depth current = 4
    //   /home/user/root-tutorials/tutorial1/html/.../anyotherpage.html => dir depth current > 4
    wxString anyTutorialPath =
            wxString( paraverMain::myParaverMain->GetParaverConfig()->getGlobalTutorialsPath().c_str() );
    if ( anyTutorialPath[ anyTutorialPath.Len() - 1 ] != wxString( wxFileName::GetPathSeparator() ))
    {
      // last separator needed to count properly
      anyTutorialPath += wxString( wxFileName::GetPathSeparator() );
    }

    wxFileName anyTutorialDir( anyTutorialPath );

    size_t dirsDepthTutorials = anyTutorialDir.GetDirCount();

    wxFileName currentLink( event.GetLinkInfo().GetHref() );
    size_t dirsDepthCurrentLink = currentLink.GetDirCount();

    if (( dirsDepthCurrentLink == dirsDepthTutorials + 1 ) &&
        ( currentLink.GetFullName().Cmp( _("index.html") ) == 0 ))
    {
      wxArrayString dirs = currentLink.GetDirs();
      currentTutorialDir = dirs[ dirsDepthCurrentLink - 1 ];
    }

    // and let the html window browse it.
    event.Skip();
  }
}

/*!
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON_CLOSE
 */

void HelpContents::OnButtonCloseClick( wxCommandEvent& event )
{
  Close();
}

/*!
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON_INDEX
 */

void HelpContents::OnButtonIndexClick( wxCommandEvent& event )
{
  buildIndex();
}

<commit_msg>*** empty log message ***<commit_after>/*****************************************************************************\
 *                        ANALYSIS PERFORMANCE TOOLS                         *
 *                                  wxparaver                                *
 *              Paraver Trace Visualization and Analysis Tool                *
 *****************************************************************************
 *     ___     This library is free software; you can redistribute it and/or *
 *    /  __         modify it under the terms of the GNU LGPL as published   *
 *   /  /  _____    by the Free Software Foundation; either version 2.1      *
 *  /  /  /     \   of the License, or (at your option) any later version.   *
 * (  (  ( B S C )                                                           *
 *  \  \  \_____/   This library is distributed in hope that it will be      *
 *   \  \__         useful but WITHOUT ANY WARRANTY; without even the        *
 *    \___          implied warranty of MERCHANTABILITY or FITNESS FOR A     *
 *                  PARTICULAR PURPOSE. See the GNU LGPL for more details.   *
 *                                                                           *
 * You should have received a copy of the GNU Lesser General Public License  *
 * along with this library; if not, write to the Free Software Foundation,   *
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA          *
 * The GNU LEsser General Public License is contained in the file COPYING.   *
 *                                 ---------                                 *
 *   Barcelona Supercomputing Center - Centro Nacional de Supercomputacion   *
\*****************************************************************************/

/* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *\
 | @file: $HeadURL$
 | @last_commit: $Date$
 | @version:     $Revision$
\* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

////@begin includes
////@end includes
#include <string>

#include "helpcontents.h"
//#include "wx/html/htmlfilt.h"

#include "paravermain.h"
////@begin XPM images
////@end XPM images

/*!
 * HelpContents type definition
 */

IMPLEMENT_DYNAMIC_CLASS( HelpContents, wxDialog )

/*!
 * HelpContents event table definition
 */

BEGIN_EVENT_TABLE( HelpContents, wxDialog )

////@begin HelpContents event table entries
  EVT_HTML_LINK_CLICKED( ID_HTMLWINDOW, HelpContents::OnHtmlwindowLinkClicked )

  EVT_BUTTON( ID_BUTTON_INDEX, HelpContents::OnButtonIndexClick )

  EVT_BUTTON( ID_BUTTON_CLOSE, HelpContents::OnButtonCloseClick )

////@end HelpContents event table entries

END_EVENT_TABLE()

/*!
 * HelpContents constructors
 */

HelpContents::HelpContents()
{
  Init();
}

HelpContents::HelpContents( wxWindow* parent,
                            wxWindowID id,
                            const wxString& caption,
                            const wxPoint& pos,
                            const wxSize& size,
                            long style )
{
  Init();
  Create(parent, id, caption, pos, size, style);
}

/*!
 * HelpContents creator
 */

bool HelpContents::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
////@begin HelpContents creation
  SetExtraStyle(wxWS_EX_BLOCK_EVENTS);
  wxDialog::Create( parent, id, caption, pos, size, style );

  CreateControls();
  if (GetSizer())
  {
    GetSizer()->SetSizeHints(this);
  }
  Centre();
////@end HelpContents creation
  return true;
}

/*!
 * HelpContents destructor
 */

HelpContents::~HelpContents()
{
}

/*!
 * Member initialisation
 */
void HelpContents::Init()
{
  currentTutorialDir = _("");
}

const wxString HelpContents::getHtmlIndex( const wxString& path )
{
  wxString htmlIndex;
  wxFileName index( path + wxFileName::GetPathSeparator() + _("index.html") );

  if ( index.FileExists() )
  {
    htmlIndex = index.GetFullPath();
  }

  return htmlIndex;
}

const wxString HelpContents::getTitle( int numTutorial, const wxString& path )
{
  wxString tutorialTitle;

  wxHtmlWindow auxHtml( this );
  auxHtml.LoadPage( path  + wxFileName::GetPathSeparator() + _("index.html") );
  tutorialTitle = auxHtml.GetOpenedPageTitle();
  if ( tutorialTitle.empty() || tutorialTitle == _("index.html") ) // never is empty !?!
  {
    string auxStrTitleFileName( path + wxFileName::GetPathSeparator() + _("tutorial_title") );
    string auxLine;

    ifstream titleFile;
    titleFile.open( auxStrTitleFileName.c_str() );
    if ( titleFile.good() )
    {
      std::getline( titleFile, auxLine );

      if ( auxLine.size() > 0 )
      {
        tutorialTitle = wxString::FromAscii( auxLine.c_str() );
      }
      else
      {
        tutorialTitle = _("Tutorial ");
        tutorialTitle << numTutorial;
      }
    }
    else
    {
      tutorialTitle = _("Tutorial ");
      tutorialTitle << numTutorial;
    }

    titleFile.close();
  }

  return tutorialTitle;
}

void HelpContents::appendTutorial( const wxString& title,
                                   const wxString& path,
                                   wxString& htmlDoc )
{
  htmlDoc += _("

") + title + _("

");
}

void HelpContents::htmlMessage( wxString& htmlDoc )
{
  htmlDoc += _("

No tutorial found!

");
/*
  htmlDoc += _("
Before going on, please have in mind that:
");
  htmlDoc += _("
");
  htmlDoc += _("
A single tutorials root directory must contain all ");
  htmlDoc += _("the tutorials directories that you want visible for wxparaver.
");
  htmlDoc += _("
In their own directories, every tutorial has a first page called <TT>index.html</TT>, and also related content (like traces, cfgs, etc.).
");
  htmlDoc += _("
You don't need to write any global tutorials page; we walk through the included tutorials ");
  htmlDoc += _("in the given root directory and build it for you.
");
  htmlDoc += _("
The tutorial title showed in this automatically built main index is read from:
");
  htmlDoc += _("
");
  htmlDoc += _("
The <TT>TITLE</TT> tag in the<TT>index.html</TT> file.
");
  htmlDoc += _("
If this tag is missing or empty, from a single line file named <TT>tutorial_title</TT>");
  htmlDoc += _(", also local to this tutorial.
");
  htmlDoc += _("
If no <TT>tutorial_title</TT> file is found, we give a numbered 'Tutorial #'.
");
  htmlDoc += _("
");
  htmlDoc += _("
");
*/
  htmlDoc += _("
Please check that root directory to tutorials is properly defined:
");
  htmlDoc += _("
");
  htmlDoc += _("
Open Preferences Window.
");
  htmlDoc += _("
Select Global tab.
");
  htmlDoc += _("
In the Default directories box, change the Tutorials root directory");
  htmlDoc += _("
The tutorials list will be immediately rebuilt after you save your ");
  htmlDoc += _("new settings clicking the Ok button in the Preferences Window.
");
  htmlDoc += _("
");
  htmlDoc += _("
If you still get this help, check these steps again, or please contact us at paraver@bsc.es.
");
}

void HelpContents::buildIndex()
{
  // get tutorials directory
  string auxStrPath = paraverMain::myParaverMain->GetParaverConfig()->getGlobalTutorialsPath();
  wxString auxPath = wxString::FromAscii( auxStrPath.c_str() );
  wxFileName tutorialsGlobalPath( auxPath );

  // open html index
  wxString tutorialsHtmlIndex, tutorialsList;
  tutorialsHtmlIndex += _("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">");
  tutorialsHtmlIndex += _("<TITLE>Tutorials</TITLE>");

  // look for tutorials directories, and for index.html inside them
  if ( wxDirExists( auxPath ) )
  {
    tutorialsList += _("
");
    int numTutorials = 0;

    wxString currentDir = wxFindFirstFile(
            tutorialsGlobalPath.GetLongPath() + wxFileName::GetPathSeparator() + _("*"),
            wxDIR );
    while( !currentDir.empty() )
    {
      wxString currentTutorialHtmlIndex( getHtmlIndex( currentDir ) );

      if ( currentTutorialHtmlIndex != _("")  )
      {
        // index.html found! => we consider this is a tutorial
        numTutorials++;

        appendTutorial( getTitle( numTutorials, currentDir ), currentTutorialHtmlIndex, tutorialsList );
      }

      currentDir = wxFindNextFile();
    }

    tutorialsList += _("
");

    if ( numTutorials == 0 )
    {
      htmlMessage( tutorialsHtmlIndex );
    }
    else
    {
      tutorialsHtmlIndex += _("

Index

");
      tutorialsHtmlIndex += tutorialsList;
    }
  }
  else
  {
    htmlMessage( tutorialsHtmlIndex );
  }

  // close html index
  tutorialsHtmlIndex += _("");

  htmlWindow->SetPage( tutorialsHtmlIndex.ToUTF8() );
}

/*!
 * Control creation for HelpContents
 */
void HelpContents::CreateControls()
{
////@begin HelpContents content construction
  HelpContents* itemDialog1 = this;

  wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
  itemDialog1->SetSizer(itemBoxSizer2);

  htmlWindow = new wxHtmlWindow( itemDialog1, ID_HTMLWINDOW, wxDefaultPosition, wxSize(600, 400), wxHW_SCROLLBAR_AUTO|wxSUNKEN_BORDER|wxHSCROLL|wxVSCROLL );
  itemBoxSizer2->Add(htmlWindow, 1, wxGROW|wxALL, 5);

  wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
  itemBoxSizer2->Add(itemBoxSizer4, 0, wxGROW|wxALL, 5);

  wxButton* itemButton5 = new wxButton( itemDialog1, ID_BUTTON_INDEX, _("Index"), wxDefaultPosition, wxDefaultSize, 0 );
  itemBoxSizer4->Add(itemButton5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

  itemBoxSizer4->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);

  wxButton* itemButton7 = new wxButton( itemDialog1, ID_BUTTON_CLOSE, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
  itemBoxSizer4->Add(itemButton7, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

////@end HelpContents content construction

  buildIndex();
}

/*!
 * Should we show tooltips?
 */

bool HelpContents::ShowToolTips()
{
  return true;
}

/*!
 * Get bitmap resources
 */

wxBitmap HelpContents::GetBitmapResource( const wxString& name )
{
  // Bitmap retrieval
////@begin HelpContents bitmap retrieval
  wxUnusedVar(name);
  return wxNullBitmap;
////@end HelpContents bitmap retrieval
}

/*!
 * Get icon resources
 */

wxIcon HelpContents::GetIconResource( const wxString& name )
{
  // Icon retrieval
////@begin HelpContents icon retrieval
  wxUnusedVar(name);
  return wxNullIcon;
////@end HelpContents icon retrieval
}

std::string HelpContents::getHrefFullPath( wxHtmlLinkEvent &event )
{
  string hrefFullPath = paraverMain::myParaverMain->GetParaverConfig()->getGlobalTutorialsPath();
  hrefFullPath += wxString( wxFileName::GetPathSeparator() ).mb_str();
  hrefFullPath += currentTutorialDir.mb_str();
  hrefFullPath += wxString( wxFileName::GetPathSeparator() ).mb_str();
  hrefFullPath += std::string( event.GetLinkInfo().GetHref().mb_str() );

  return hrefFullPath;
}

bool HelpContents::matchHrefExtension( wxHtmlLinkEvent &event, const wxString extension )
{
  return ( event.GetLinkInfo().GetHref().Right( extension.Len() ).Cmp( extension ) == 0 );
}

/*!
 * wxEVT_COMMAND_HTML_LINK_CLICKED event handler for ID_HTMLWINDOW
 */

void HelpContents::OnHtmlwindowLinkClicked( wxHtmlLinkEvent& event )
{
  if ( matchHrefExtension( event, _(".prv") ) || matchHrefExtension( event, _(".prv.gz")))
  {
    paraverMain::myParaverMain->DoLoadTrace( getHrefFullPath( event ) );
  }
  else if ( matchHrefExtension( event, _(".cfg")))
  {
    if ( paraverMain::myParaverMain->GetLoadedTraces().size() > 0 )
    {
      paraverMain::myParaverMain->DoLoadCFG( getHrefFullPath( event )  );
    }
    else
    {
      wxMessageDialog message( this, _("No trace loaded."), _( "Warning" ), wxOK );
      message.ShowModal();
    }
  }
  else if ( event.GetLinkInfo().GetHref().Cmp( _("init_preferences") ) == 0 )
  {
    paraverMain::myParaverMain->ShowPreferences();

    // we rebuild it anyway
    buildIndex();
  }
  else
  {
    // If current clicked link points to a tutorial index.html file, keep its
    //   tutorial directory name to allow relative references.
    // Idea to detect tutorial:
    //   /home/user/root-tutorials/ => dir depth tutorials = 3
    //   vs.
    //   /home/user/root-tutorials/tutorial1/index.html => dir depth current = 4
    //   /home/user/root-tutorials/tutorial1/html/.../anyotherpage.html => dir depth current > 4
    wxString anyTutorialPath =
            wxString( paraverMain::myParaverMain->GetParaverConfig()->getGlobalTutorialsPath().c_str() );
    if ( anyTutorialPath[ anyTutorialPath.Len() - 1 ] != wxString( wxFileName::GetPathSeparator() ))
    {
      // last separator needed to count properly
      anyTutorialPath += wxString( wxFileName::GetPathSeparator() );
    }

    wxFileName anyTutorialDir( anyTutorialPath );

    size_t dirsDepthTutorials = anyTutorialDir.GetDirCount();

    wxFileName currentLink( event.GetLinkInfo().GetHref() );
    size_t dirsDepthCurrentLink = currentLink.GetDirCount();

    if (( dirsDepthCurrentLink == dirsDepthTutorials + 1 ) &&
        ( currentLink.GetFullName().Cmp( _("index.html") ) == 0 ))
    {
      wxArrayString dirs = currentLink.GetDirs();
      currentTutorialDir = dirs[ dirsDepthCurrentLink - 1 ];
    }

    // and let the html window browse it.
    event.Skip();
  }
}

/*!
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON_CLOSE
 */

void HelpContents::OnButtonCloseClick( wxCommandEvent& event )
{
  Close();
}

/*!
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON_INDEX
 */

void HelpContents::OnButtonIndexClick( wxCommandEvent& event )
{
  buildIndex();
}

<|endoftext|>


<commit_before>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2014 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "EaseInOutAnim.h"

#include "../player/Player.h"
#include "../base/MathHelper.h"

#include <math.h>

using namespace boost::python;
using namespace std;

namespace avg {

EaseInOutAnim::EaseInOutAnim(const object& node, const string& sAttrName,
            long long duration, const object& startValue, const object& endValue,
            long long easeInDuration, long long easeOutDuration, bool bUseInt,
            const object& startCallback, const object& stopCallback)
    : SimpleAnim(node, sAttrName, duration, startValue, endValue, bUseInt, startCallback,
            stopCallback),
      m_EaseInDuration(float(easeInDuration)/duration),
      m_EaseOutDuration(float(easeOutDuration)/duration)
{
}

EaseInOutAnim::~EaseInOutAnim()
{
}

float EaseInOutAnim::interpolate(float t)
{
    float accelDist = m_EaseInDuration*2/M_PI;
    float decelDist = m_EaseOutDuration*2/M_PI;
    float dist;
    if (t<m_EaseInDuration) {
        // Acceleration stage
        float nt = t/m_EaseInDuration;
        float s = sin(-M_PI/2+nt*M_PI/2)+1;
        dist = s*accelDist;
    } else if (t > 1-m_EaseOutDuration) {
        // Deceleration stage
        float nt = (t-(1-m_EaseOutDuration))/m_EaseOutDuration;
        float s = sin(nt*M_PI/2);
        dist = accelDist+(1-m_EaseInDuration-m_EaseOutDuration)+s*decelDist;
    } else {
        // Linear stage
        dist = accelDist+t-m_EaseInDuration;
    }
    return dist/(accelDist+(1-m_EaseInDuration-m_EaseOutDuration)+decelDist);
}

}
<commit_msg>Windows warning fix.<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2014 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "EaseInOutAnim.h"

#include "../player/Player.h"
#include "../base/MathHelper.h"

#include <math.h>

using namespace boost::python;
using namespace std;

namespace avg {

EaseInOutAnim::EaseInOutAnim(const object& node, const string& sAttrName,
            long long duration, const object& startValue, const object& endValue,
            long long easeInDuration, long long easeOutDuration, bool bUseInt,
            const object& startCallback, const object& stopCallback)
    : SimpleAnim(node, sAttrName, duration, startValue, endValue, bUseInt, startCallback,
            stopCallback),
      m_EaseInDuration(float(easeInDuration)/duration),
      m_EaseOutDuration(float(easeOutDuration)/duration)
{
}

EaseInOutAnim::~EaseInOutAnim()
{
}

float EaseInOutAnim::interpolate(float t)
{
    float accelDist = m_EaseInDuration*2/float(M_PI);
    float decelDist = m_EaseOutDuration*2/float(M_PI);
    float dist;
    if (t<m_EaseInDuration) {
        // Acceleration stage
        float nt = t/m_EaseInDuration;
        float s = float(sin(-M_PI/2+nt*M_PI/2)+1);
        dist = s*accelDist;
    } else if (t > 1-m_EaseOutDuration) {
        // Deceleration stage
        float nt = (t-(1-m_EaseOutDuration))/m_EaseOutDuration;
        float s = sin(nt*float(M_PI)/2);
        dist = accelDist+(1-m_EaseInDuration-m_EaseOutDuration)+s*decelDist;
    } else {
        // Linear stage
        dist = accelDist+t-m_EaseInDuration;
    }
    return dist/(accelDist+(1-m_EaseInDuration-m_EaseOutDuration)+decelDist);
}

}
<|endoftext|>


<commit_before>// Copyright 2018 The clvk authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "device.hpp"
#include "memory.hpp"
#include "utils.hpp"

cvk_device* cvk_device::create(VkPhysicalDevice pdev) {
    cvk_device* device = new cvk_device(pdev);

    if (!device->init()) {
        delete device;
        return nullptr;
    }

    return device;
}

bool cvk_device::init_queues(uint32_t* num_queues, uint32_t* queue_family) {
    // Get number of queue families
    uint32_t num_families;
    vkGetPhysicalDeviceQueueFamilyProperties(m_pdev, &num_families, nullptr);

    cvk_info_fn(
        "physical device (%s) has %u queue families:",
        vulkan_physical_device_type_string(m_properties.deviceType).c_str(),
        num_families);

    // Get their properties
    std::vector<VkQueueFamilyProperties> families(num_families);
    vkGetPhysicalDeviceQueueFamilyProperties(m_pdev, &num_families,
                                             families.data());

    // Look for suitable queues
    bool found_queues = false;
    *num_queues = 0;
    for (uint32_t i = 0; i < num_families; i++) {

        cvk_info_fn("queue family %u: %2u queues | %s", i,
                    families[i].queueCount,
                    vulkan_queue_flags_string(families[i].queueFlags).c_str());

        if (!found_queues && (families[i].queueFlags & VK_QUEUE_COMPUTE_BIT)) {
            *queue_family = i;
            *num_queues = families[i].queueCount;
            found_queues = true;
        }
    }

    if (!found_queues) {
        cvk_error("Could not find a suitable queue family for this device");
        return false;
    }

    // Initialise the queue allocator
    m_vulkan_queue_alloc_index = 0;

    return true;
}

bool cvk_device::init_extensions() {
    uint32_t numext;
    VkResult res =
        vkEnumerateDeviceExtensionProperties(m_pdev, nullptr, &numext, nullptr);
    CVK_VK_CHECK_ERROR_RET(
        res, false, "Failed to get the number of device extension properties");

    cvk_info("%u device extension properties reported.", numext);

    std::vector<VkExtensionProperties> extensions(numext);
    res = vkEnumerateDeviceExtensionProperties(m_pdev, nullptr, &numext,
                                               extensions.data());
    CVK_VK_CHECK_ERROR_RET(res, false,
                           "Could not enumerate device extension properties");

    if (m_properties.apiVersion < VK_MAKE_VERSION(1, 1, 0)) {
        m_vulkan_device_extensions.push_back(
            VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME);
        m_vulkan_device_extensions.push_back(
            VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
    }

    const std::vector<const char*> desired_extensions = {
        VK_KHR_16BIT_STORAGE_EXTENSION_NAME,
        VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME,
        VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME,
        VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME,
    };

    for (size_t i = 0; i < numext; i++) {
        cvk_info("Found extension %s, spec version %u",
                 extensions[i].extensionName, extensions[i].specVersion);

        for (auto de : desired_extensions) {
            if (!strcmp(de, extensions[i].extensionName)) {
                m_vulkan_device_extensions.push_back(de);
                cvk_info_fn("found extension %s, enabling", de);
            }
        }
    }

    return true;
}

void cvk_device::init_features() {
    // Query supported features.
    m_features_ubo_stdlayout.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR;
    m_features_ubo_stdlayout.pNext = nullptr;

    m_features_float16_int8.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR;
    m_features_float16_int8.pNext = &m_features_ubo_stdlayout;

    m_features_variable_pointer.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES;
    m_features_variable_pointer.pNext = &m_features_float16_int8;

    VkPhysicalDeviceFeatures2 supported_features;
    supported_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
    supported_features.pNext = &m_features_variable_pointer;

    vkGetPhysicalDeviceFeatures2(m_pdev, &supported_features);

    // Selectively enable core features.
    memset(&m_features, 0, sizeof(m_features));

    if (supported_features.features.shaderInt16) {
        m_features.features.shaderInt16 = VK_TRUE;
    }
    if (supported_features.features.shaderInt64) {
        m_features.features.shaderInt64 = VK_TRUE;
    }
    if (supported_features.features.shaderFloat64) {
        m_features.features.shaderFloat64 = VK_TRUE;
    }
    if (supported_features.features.shaderStorageImageWriteWithoutFormat) {
        m_features.features.shaderStorageImageWriteWithoutFormat = VK_TRUE;
    }

    // All queried extended features are enabled when supported.
    m_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
    m_features.pNext = &m_features_variable_pointer;
}

void cvk_device::construct_extension_string() {

    // Start with required extensions
    m_extensions = "cl_khr_global_int32_base_atomics "
                   "cl_khr_global_int32_extended_atomics "
                   "cl_khr_local_int32_base_atomics "
                   "cl_khr_local_int32_extended_atomics "
                   "cl_khr_byte_addressable_store ";

    // Add always supported extension
#ifndef CLSPV_ONLINE_COMPILER
    m_extensions += "cl_khr_il_program ";
#endif
}

bool cvk_device::create_vulkan_queues_and_device(uint32_t num_queues,
                                                 uint32_t queue_family) {
    // Give all queues the same priority
    std::vector<float> queuePriorities(num_queues, 1.0f);

    VkDeviceQueueCreateInfo queueCreateInfo = {
        VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
        nullptr,
        0, // flags
        queue_family,
        num_queues, // queueCount
        queuePriorities.data()};

    // Create logical device
    const VkDeviceCreateInfo createInfo = {
        VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
        &m_features,                          // pNext
        0,                                    // flags
        1,                                    // queueCreateInfoCount
        &queueCreateInfo,                     // pQueueCreateInfos,
        0,                                    // enabledLayerCount
        nullptr,                              // ppEnabledLayerNames
        static_cast<uint32_t>(
            m_vulkan_device_extensions.size()), // enabledExtensionCount
        m_vulkan_device_extensions.data(),      // ppEnabledExtensionNames
        nullptr,                                // pEnabledFeatures
    };

    VkResult res = vkCreateDevice(m_pdev, &createInfo, nullptr, &m_dev);
    CVK_VK_CHECK_ERROR_RET(res, false, "Failed to create a device");

    // Construct the queue wrappers now that our queues exist
    for (auto i = 0U; i < num_queues; i++) {
        VkQueue queue;

        vkGetDeviceQueue(m_dev, queue_family, i, &queue);
        m_vulkan_queues.emplace_back(
            cvk_vulkan_queue_wrapper(queue, queue_family));
    }

    return true;
}

bool cvk_device::compute_buffer_alignement_requirements() {
    // Work out the required alignment for buffers
    const VkBufferCreateInfo bufferCreateInfo = {
        VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
        nullptr,                              // pNext
        0,                                    // flags
        1,                                    // size
        cvk_buffer::USAGE_FLAGS,              // usage
        VK_SHARING_MODE_EXCLUSIVE,
        0,       // queueFamilyIndexCount
        nullptr, // pQueueFamilyIndices
    };

    VkBuffer buffer;
    auto res = vkCreateBuffer(m_dev, &bufferCreateInfo, nullptr, &buffer);
    CVK_VK_CHECK_ERROR_RET(res, false, "Failed to create a buffer");

    VkMemoryRequirements memreqs;
    vkGetBufferMemoryRequirements(m_dev, buffer, &memreqs);

    uint32_t alignment_bits = memreqs.alignment * 8;
    // The OpenCL spec requires at least 1024 bits (long16's alignment)
    m_mem_base_addr_align = std::max(alignment_bits, 1024u);
    vkDestroyBuffer(m_dev, buffer, nullptr);

    return true;
}

void cvk_device::log_limits_and_memory_information() {
    // Print relevant device limits
    const VkPhysicalDeviceLimits& limits = vulkan_limits();
    cvk_info_fn("device's resources per stage limits:");
    cvk_info_fn("    total = %u", limits.maxPerStageResources);
    cvk_info_fn("    uniform buffers = %u",
                limits.maxPerStageDescriptorUniformBuffers);
    cvk_info_fn("    storage buffers = %u",
                limits.maxPerStageDescriptorStorageBuffers);
    cvk_info_fn("device's max buffer size = %s",
                pretty_size(limits.maxStorageBufferRange).c_str());

    // Print memoy information
    cvk_info_fn("device has %u memory types:",
                m_mem_properties.memoryTypeCount);
    for (uint32_t i = 0; i < m_mem_properties.memoryTypeCount; i++) {
        VkMemoryType memtype = m_mem_properties.memoryTypes[i];
        auto heapsize = m_mem_properties.memoryHeaps[memtype.heapIndex].size;
        cvk_info_fn(
            "    %u: heap = %u, %s | %s", i, memtype.heapIndex,
            pretty_size(heapsize).c_str(),
            vulkan_memory_property_flags_string(memtype.propertyFlags).c_str());
    }

    cvk_info_fn("device has %u memory heaps:",
                m_mem_properties.memoryHeapCount);
    for (uint32_t i = 0; i < m_mem_properties.memoryHeapCount; i++) {
        VkMemoryHeap memheap = m_mem_properties.memoryHeaps[i];
        cvk_info_fn("    %u: %s | %s", i, pretty_size(memheap.size).c_str(),
                    vulkan_memory_property_flags_string(memheap.flags).c_str());
    }
}

bool cvk_device::init() {
    cvk_info_fn("Initialising device %s", m_properties.deviceName);

    uint32_t num_queues, queue_family;
    if (!init_queues(&num_queues, &queue_family)) {
        return false;
    }

    if (!init_extensions()) {
        return false;
    }

    init_features();

    construct_extension_string();

    if (!create_vulkan_queues_and_device(num_queues, queue_family)) {
        return false;
    }

    if (!compute_buffer_alignement_requirements()) {
        return false;
    }

    log_limits_and_memory_information();

    return true;
}

bool cvk_device::supports_capability(spv::Capability capability) const {
    switch (capability) {
    // Capabilities required by all Vulkan implementations:
    case spv::CapabilityShader:
    case spv::CapabilitySampled1D:
    case spv::CapabilityImage1D:
    case spv::CapabilityImageQuery:
        return true;
    // Optional capabilities:
    case spv::CapabilityFloat16:
        return m_features_float16_int8.shaderFloat16;
    case spv::CapabilityFloat64:
        return m_features.features.shaderFloat64;
    case spv::CapabilityInt8:
        return m_features_float16_int8.shaderInt8;
    case spv::CapabilityInt16:
        return m_features.features.shaderInt16;
    case spv::CapabilityInt64:
        return m_features.features.shaderInt64;
    case spv::CapabilityStorageImageWriteWithoutFormat:
        return m_features.features.shaderStorageImageWriteWithoutFormat;
    case spv::CapabilityVariablePointers:
        return m_features_variable_pointer.variablePointers;
    case spv::CapabilityVariablePointersStorageBuffer:
        return m_features_variable_pointer.variablePointersStorageBuffer;
    // Capabilities that have not yet been mapped to Vulkan features:
    default:
        cvk_warn_fn("Capability %d not yet mapped to a feature.", capability);
        return false;
    }
}
<commit_msg>Don't request physical device properties2 as device extension (#150)<commit_after>// Copyright 2018 The clvk authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "device.hpp"
#include "memory.hpp"
#include "utils.hpp"

cvk_device* cvk_device::create(VkPhysicalDevice pdev) {
    cvk_device* device = new cvk_device(pdev);

    if (!device->init()) {
        delete device;
        return nullptr;
    }

    return device;
}

bool cvk_device::init_queues(uint32_t* num_queues, uint32_t* queue_family) {
    // Get number of queue families
    uint32_t num_families;
    vkGetPhysicalDeviceQueueFamilyProperties(m_pdev, &num_families, nullptr);

    cvk_info_fn(
        "physical device (%s) has %u queue families:",
        vulkan_physical_device_type_string(m_properties.deviceType).c_str(),
        num_families);

    // Get their properties
    std::vector<VkQueueFamilyProperties> families(num_families);
    vkGetPhysicalDeviceQueueFamilyProperties(m_pdev, &num_families,
                                             families.data());

    // Look for suitable queues
    bool found_queues = false;
    *num_queues = 0;
    for (uint32_t i = 0; i < num_families; i++) {

        cvk_info_fn("queue family %u: %2u queues | %s", i,
                    families[i].queueCount,
                    vulkan_queue_flags_string(families[i].queueFlags).c_str());

        if (!found_queues && (families[i].queueFlags & VK_QUEUE_COMPUTE_BIT)) {
            *queue_family = i;
            *num_queues = families[i].queueCount;
            found_queues = true;
        }
    }

    if (!found_queues) {
        cvk_error("Could not find a suitable queue family for this device");
        return false;
    }

    // Initialise the queue allocator
    m_vulkan_queue_alloc_index = 0;

    return true;
}

bool cvk_device::init_extensions() {
    uint32_t numext;
    VkResult res =
        vkEnumerateDeviceExtensionProperties(m_pdev, nullptr, &numext, nullptr);
    CVK_VK_CHECK_ERROR_RET(
        res, false, "Failed to get the number of device extension properties");

    cvk_info("%u device extension properties reported.", numext);

    std::vector<VkExtensionProperties> extensions(numext);
    res = vkEnumerateDeviceExtensionProperties(m_pdev, nullptr, &numext,
                                               extensions.data());
    CVK_VK_CHECK_ERROR_RET(res, false,
                           "Could not enumerate device extension properties");

    if (m_properties.apiVersion < VK_MAKE_VERSION(1, 1, 0)) {
        m_vulkan_device_extensions.push_back(
            VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME);
    }

    const std::vector<const char*> desired_extensions = {
        VK_KHR_16BIT_STORAGE_EXTENSION_NAME,
        VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME,
        VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME,
        VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME,
    };

    for (size_t i = 0; i < numext; i++) {
        cvk_info("Found extension %s, spec version %u",
                 extensions[i].extensionName, extensions[i].specVersion);

        for (auto de : desired_extensions) {
            if (!strcmp(de, extensions[i].extensionName)) {
                m_vulkan_device_extensions.push_back(de);
                cvk_info_fn("found extension %s, enabling", de);
            }
        }
    }

    return true;
}

void cvk_device::init_features() {
    // Query supported features.
    m_features_ubo_stdlayout.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR;
    m_features_ubo_stdlayout.pNext = nullptr;

    m_features_float16_int8.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR;
    m_features_float16_int8.pNext = &m_features_ubo_stdlayout;

    m_features_variable_pointer.sType =
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES;
    m_features_variable_pointer.pNext = &m_features_float16_int8;

    VkPhysicalDeviceFeatures2 supported_features;
    supported_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
    supported_features.pNext = &m_features_variable_pointer;

    vkGetPhysicalDeviceFeatures2(m_pdev, &supported_features);

    // Selectively enable core features.
    memset(&m_features, 0, sizeof(m_features));

    if (supported_features.features.shaderInt16) {
        m_features.features.shaderInt16 = VK_TRUE;
    }
    if (supported_features.features.shaderInt64) {
        m_features.features.shaderInt64 = VK_TRUE;
    }
    if (supported_features.features.shaderFloat64) {
        m_features.features.shaderFloat64 = VK_TRUE;
    }
    if (supported_features.features.shaderStorageImageWriteWithoutFormat) {
        m_features.features.shaderStorageImageWriteWithoutFormat = VK_TRUE;
    }

    // All queried extended features are enabled when supported.
    m_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
    m_features.pNext = &m_features_variable_pointer;
}

void cvk_device::construct_extension_string() {

    // Start with required extensions
    m_extensions = "cl_khr_global_int32_base_atomics "
                   "cl_khr_global_int32_extended_atomics "
                   "cl_khr_local_int32_base_atomics "
                   "cl_khr_local_int32_extended_atomics "
                   "cl_khr_byte_addressable_store ";

    // Add always supported extension
#ifndef CLSPV_ONLINE_COMPILER
    m_extensions += "cl_khr_il_program ";
#endif
}

bool cvk_device::create_vulkan_queues_and_device(uint32_t num_queues,
                                                 uint32_t queue_family) {
    // Give all queues the same priority
    std::vector<float> queuePriorities(num_queues, 1.0f);

    VkDeviceQueueCreateInfo queueCreateInfo = {
        VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
        nullptr,
        0, // flags
        queue_family,
        num_queues, // queueCount
        queuePriorities.data()};

    // Create logical device
    const VkDeviceCreateInfo createInfo = {
        VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
        &m_features,                          // pNext
        0,                                    // flags
        1,                                    // queueCreateInfoCount
        &queueCreateInfo,                     // pQueueCreateInfos,
        0,                                    // enabledLayerCount
        nullptr,                              // ppEnabledLayerNames
        static_cast<uint32_t>(
            m_vulkan_device_extensions.size()), // enabledExtensionCount
        m_vulkan_device_extensions.data(),      // ppEnabledExtensionNames
        nullptr,                                // pEnabledFeatures
    };

    VkResult res = vkCreateDevice(m_pdev, &createInfo, nullptr, &m_dev);
    CVK_VK_CHECK_ERROR_RET(res, false, "Failed to create a device");

    // Construct the queue wrappers now that our queues exist
    for (auto i = 0U; i < num_queues; i++) {
        VkQueue queue;

        vkGetDeviceQueue(m_dev, queue_family, i, &queue);
        m_vulkan_queues.emplace_back(
            cvk_vulkan_queue_wrapper(queue, queue_family));
    }

    return true;
}

bool cvk_device::compute_buffer_alignement_requirements() {
    // Work out the required alignment for buffers
    const VkBufferCreateInfo bufferCreateInfo = {
        VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
        nullptr,                              // pNext
        0,                                    // flags
        1,                                    // size
        cvk_buffer::USAGE_FLAGS,              // usage
        VK_SHARING_MODE_EXCLUSIVE,
        0,       // queueFamilyIndexCount
        nullptr, // pQueueFamilyIndices
    };

    VkBuffer buffer;
    auto res = vkCreateBuffer(m_dev, &bufferCreateInfo, nullptr, &buffer);
    CVK_VK_CHECK_ERROR_RET(res, false, "Failed to create a buffer");

    VkMemoryRequirements memreqs;
    vkGetBufferMemoryRequirements(m_dev, buffer, &memreqs);

    uint32_t alignment_bits = memreqs.alignment * 8;
    // The OpenCL spec requires at least 1024 bits (long16's alignment)
    m_mem_base_addr_align = std::max(alignment_bits, 1024u);
    vkDestroyBuffer(m_dev, buffer, nullptr);

    return true;
}

void cvk_device::log_limits_and_memory_information() {
    // Print relevant device limits
    const VkPhysicalDeviceLimits& limits = vulkan_limits();
    cvk_info_fn("device's resources per stage limits:");
    cvk_info_fn("    total = %u", limits.maxPerStageResources);
    cvk_info_fn("    uniform buffers = %u",
                limits.maxPerStageDescriptorUniformBuffers);
    cvk_info_fn("    storage buffers = %u",
                limits.maxPerStageDescriptorStorageBuffers);
    cvk_info_fn("device's max buffer size = %s",
                pretty_size(limits.maxStorageBufferRange).c_str());

    // Print memoy information
    cvk_info_fn("device has %u memory types:",
                m_mem_properties.memoryTypeCount);
    for (uint32_t i = 0; i < m_mem_properties.memoryTypeCount; i++) {
        VkMemoryType memtype = m_mem_properties.memoryTypes[i];
        auto heapsize = m_mem_properties.memoryHeaps[memtype.heapIndex].size;
        cvk_info_fn(
            "    %u: heap = %u, %s | %s", i, memtype.heapIndex,
            pretty_size(heapsize).c_str(),
            vulkan_memory_property_flags_string(memtype.propertyFlags).c_str());
    }

    cvk_info_fn("device has %u memory heaps:",
                m_mem_properties.memoryHeapCount);
    for (uint32_t i = 0; i < m_mem_properties.memoryHeapCount; i++) {
        VkMemoryHeap memheap = m_mem_properties.memoryHeaps[i];
        cvk_info_fn("    %u: %s | %s", i, pretty_size(memheap.size).c_str(),
                    vulkan_memory_property_flags_string(memheap.flags).c_str());
    }
}

bool cvk_device::init() {
    cvk_info_fn("Initialising device %s", m_properties.deviceName);

    uint32_t num_queues, queue_family;
    if (!init_queues(&num_queues, &queue_family)) {
        return false;
    }

    if (!init_extensions()) {
        return false;
    }

    init_features();

    construct_extension_string();

    if (!create_vulkan_queues_and_device(num_queues, queue_family)) {
        return false;
    }

    if (!compute_buffer_alignement_requirements()) {
        return false;
    }

    log_limits_and_memory_information();

    return true;
}

bool cvk_device::supports_capability(spv::Capability capability) const {
    switch (capability) {
    // Capabilities required by all Vulkan implementations:
    case spv::CapabilityShader:
    case spv::CapabilitySampled1D:
    case spv::CapabilityImage1D:
    case spv::CapabilityImageQuery:
        return true;
    // Optional capabilities:
    case spv::CapabilityFloat16:
        return m_features_float16_int8.shaderFloat16;
    case spv::CapabilityFloat64:
        return m_features.features.shaderFloat64;
    case spv::CapabilityInt8:
        return m_features_float16_int8.shaderInt8;
    case spv::CapabilityInt16:
        return m_features.features.shaderInt16;
    case spv::CapabilityInt64:
        return m_features.features.shaderInt64;
    case spv::CapabilityStorageImageWriteWithoutFormat:
        return m_features.features.shaderStorageImageWriteWithoutFormat;
    case spv::CapabilityVariablePointers:
        return m_features_variable_pointer.variablePointers;
    case spv::CapabilityVariablePointersStorageBuffer:
        return m_features_variable_pointer.variablePointersStorageBuffer;
    // Capabilities that have not yet been mapped to Vulkan features:
    default:
        cvk_warn_fn("Capability %d not yet mapped to a feature.", capability);
        return false;
    }
}
<|endoftext|>


<commit_before>#include <osg/UnitTestFramework>
#include <osg/ArgumentParser>
#include <osg/ApplicationUsage>

#include <osg/Vec3>
#include <osg/Matrix>

#include <iostream>

void testFrustum(double left,double right,double bottom,double top,double zNear,double zFar)
{
    osg::Matrix f;
    f.makeFrustum(left,right,bottom,top,zNear,zFar);

    double c_left=0;
    double c_right=0;
    double c_top=0;
    double c_bottom=0;
    double c_zNear=0;
    double c_zFar=0;

    std::cout << "testFrustum"<<f.getFrustum(c_left,c_right,c_bottom,c_top,c_zNear,c_zFar)<<std::endl;
    std::cout << "  left = "<<left<<" compute "<<c_left<<std::endl;
    std::cout << "  right = "<<right<<" compute "<<c_right<<std::endl;

    std::cout << "  bottom = "<<bottom<<" compute "<<c_bottom<<std::endl;
    std::cout << "  top = "<<top<<" compute "<<c_top<<std::endl;

    std::cout << "  zNear = "<<zNear<<" compute "<<c_zNear<<std::endl;
    std::cout << "  zFar = "<<zFar<<" compute "<<c_zFar<<std::endl;

    std::cout << std::endl;
}

void testOrtho(double left,double right,double bottom,double top,double zNear,double zFar)
{
    osg::Matrix f;
    f.makeOrtho(left,right,bottom,top,zNear,zFar);

    double c_left=0;
    double c_right=0;
    double c_top=0;
    double c_bottom=0;
    double c_zNear=0;
    double c_zFar=0;

    std::cout << "testOrtho "<< f.getOrtho(c_left,c_right,c_bottom,c_top,c_zNear,c_zFar) << std::endl;
    std::cout << "  left = "<<left<<" compute "<<c_left<<std::endl;
    std::cout << "  right = "<<right<<" compute "<<c_right<<std::endl;

    std::cout << "  bottom = "<<bottom<<" compute "<<c_bottom<<std::endl;
    std::cout << "  top = "<<top<<" compute "<<c_top<<std::endl;

    std::cout << "  zNear = "<<zNear<<" compute "<<c_zNear<<std::endl;
    std::cout << "  zFar = "<<zFar<<" compute "<<c_zFar<<std::endl;

    std::cout << std::endl;
}

void testPerspective(double fovy,double aspect,double zNear,double zFar)
{
    osg::Matrix f;
    f.makePerspective(fovy,aspect,zNear,zFar);

    double c_fovy=0;
    double c_aspect=0;
    double c_zNear=0;
    double c_zFar=0;

    std::cout << "testPerspective "<< f.getPerspective(c_fovy,c_aspect,c_zNear,c_zFar) << std::endl;
    std::cout << "  fovy = "<<fovy<<" compute "<<c_fovy<<std::endl;
    std::cout << "  aspect = "<<aspect<<" compute "<<c_aspect<<std::endl;

    std::cout << "  zNear = "<<zNear<<" compute "<<c_zNear<<std::endl;
    std::cout << "  zFar = "<<zFar<<" compute "<<c_zFar<<std::endl;

    std::cout << std::endl;
}

void testLookAt(const osg::Vec3& eye,const osg::Vec3& center,const osg::Vec3& up)
{
    osg::Matrix mv;
    mv.makeLookAt(eye,center,up);

    osg::Vec3 c_eye,c_center,c_up;
    mv.getLookAt(c_eye,c_center,c_up);

    std::cout << "testLookAt"<<std::endl;
    std::cout << "  eye "<<eye<< " compute "<<c_eye<<std::endl;
    std::cout << "  eye "<<center<< " compute "<<c_center<<std::endl;
    std::cout << "  eye "<<up<< " compute "<<c_up<<std::endl;

    std::cout << std::endl;

}

void sizeOfTest()
{
  std::cout<<"sizeof(bool)=="<<sizeof(bool)<<std::endl;
  std::cout<<"sizeof(char)=="<<sizeof(char)<<std::endl;
  std::cout<<"sizeof(short)=="<<sizeof(short)<<std::endl;
  std::cout<<"sizeof(int)=="<<sizeof(int)<<std::endl;
  std::cout<<"sizeof(long)=="<<sizeof(long)<<std::endl;
  std::cout<<"sizeof(long int)=="<<sizeof(long int)<<std::endl;

#if defined(_MSC_VER)
  // long long isn't supported on VS6.0...
  std::cout<<"sizeof(__int64)=="<<sizeof(__int64)<<std::endl;
#else
  std::cout<<"sizeof(long long)=="<<sizeof(long long)<<std::endl;
#endif
  std::cout<<"sizeof(float)=="<<sizeof(float)<<std::endl;
  std::cout<<"sizeof(double)=="<<sizeof(double)<<std::endl;
}

int main( int argc, char** argv )
{
    osg::ArgumentParser arguments(&argc,argv);

    // set up the usage document, in case we need to print out how to use this program.
    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which runs units tests.");
    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options]");
    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
    arguments.getApplicationUsage()->addCommandLineOption("qt","Display qualified tests.");
    arguments.getApplicationUsage()->addCommandLineOption("sizeof","Display sizeof tests.");
    arguments.getApplicationUsage()->addCommandLineOption("matrix","Display qualified tests.");

    if (arguments.argc()<=1)
    {
        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
        return 1;
    }

    bool printQualifiedTest = false;
    while (arguments.read("qt")) printQualifiedTest = true;

    bool printMatrixTest = false;
    while (arguments.read("matrix")) printMatrixTest = true;

    bool printSizeOfTest = false;
    while (arguments.read("sizeof")) printSizeOfTest = true;

    // if user request help write it out to cout.
    if (arguments.read("-h") || arguments.read("--help"))
    {
        std::cout<<arguments.getApplicationUsage()->getCommandLineUsage()<<std::endl;
        arguments.getApplicationUsage()->write(std::cout,arguments.getApplicationUsage()->getCommandLineOptions());
        return 1;
    }

    // any option left unread are converted into errors to write out later.
    arguments.reportRemainingOptionsAsUnrecognized();

    // report any errors if they have occured when parsing the program aguments.
    if (arguments.errors())
    {
        arguments.writeErrorMessages(std::cout);
        return 1;
    }

    if (printMatrixTest)
    {
        std::cout<<"******   Running matrix tests   ******"<<std::endl;

        testFrustum(-1,1,-1,1,1,1000);
        testFrustum(0,1,1,2,2.5,100000);

        testOrtho(0,1,1,2,2.1,1000);
        testOrtho(-1,10,1,20,2.5,100000);

        testPerspective(20,1,1,1000);
        testPerspective(90,2,1,1000);

        testLookAt(osg::Vec3(10.0,4.0,2.0),osg::Vec3(10.0,4.0,2.0)+osg::Vec3(0.0,1.0,0.0),osg::Vec3(0.0,0.0,1.0));
        testLookAt(osg::Vec3(10.0,4.0,2.0),osg::Vec3(10.0,4.0,2.0)+osg::Vec3(1.0,1.0,0.0),osg::Vec3(0.0,0.0,1.0));

    }

    if (printSizeOfTest)
    {
        std::cout<<"**** sizeof() tests  ******"<<std::endl;

        sizeOfTest();

        std::cout<<std::endl;
    }

    if (printQualifiedTest)
    {
         std::cout<<"*****   Qualified Tests  ******"<<std::endl;

         osgUtx::QualifiedTestPrinter printer;
         osgUtx::TestGraph::instance().root()->accept( printer );
         std::cout<<std::endl;
    }

    std::cout<<"******   Running tests   ******"<<std::endl;

    // Global Data or Context
    osgUtx::TestContext ctx;
    osgUtx::TestRunner runner( ctx );
    runner.specify("root");

    osgUtx::TestGraph::instance().root()->accept( runner );

    return 0;
}
<commit_msg>Added test for quat multiplication ordering.<commit_after>#include <osg/UnitTestFramework>
#include <osg/ArgumentParser>
#include <osg/ApplicationUsage>

#include <osg/Vec3>
#include <osg/Matrix>

#include <iostream>

void testFrustum(double left,double right,double bottom,double top,double zNear,double zFar)
{
    osg::Matrix f;
    f.makeFrustum(left,right,bottom,top,zNear,zFar);

    double c_left=0;
    double c_right=0;
    double c_top=0;
    double c_bottom=0;
    double c_zNear=0;
    double c_zFar=0;

    std::cout << "testFrustum"<<f.getFrustum(c_left,c_right,c_bottom,c_top,c_zNear,c_zFar)<<std::endl;
    std::cout << "  left = "<<left<<" compute "<<c_left<<std::endl;
    std::cout << "  right = "<<right<<" compute "<<c_right<<std::endl;

    std::cout << "  bottom = "<<bottom<<" compute "<<c_bottom<<std::endl;
    std::cout << "  top = "<<top<<" compute "<<c_top<<std::endl;

    std::cout << "  zNear = "<<zNear<<" compute "<<c_zNear<<std::endl;
    std::cout << "  zFar = "<<zFar<<" compute "<<c_zFar<<std::endl;

    std::cout << std::endl;
}

void testOrtho(double left,double right,double bottom,double top,double zNear,double zFar)
{
    osg::Matrix f;
    f.makeOrtho(left,right,bottom,top,zNear,zFar);

    double c_left=0;
    double c_right=0;
    double c_top=0;
    double c_bottom=0;
    double c_zNear=0;
    double c_zFar=0;

    std::cout << "testOrtho "<< f.getOrtho(c_left,c_right,c_bottom,c_top,c_zNear,c_zFar) << std::endl;
    std::cout << "  left = "<<left<<" compute "<<c_left<<std::endl;
    std::cout << "  right = "<<right<<" compute "<<c_right<<std::endl;

    std::cout << "  bottom = "<<bottom<<" compute "<<c_bottom<<std::endl;
    std::cout << "  top = "<<top<<" compute "<<c_top<<std::endl;

    std::cout << "  zNear = "<<zNear<<" compute "<<c_zNear<<std::endl;
    std::cout << "  zFar = "<<zFar<<" compute "<<c_zFar<<std::endl;

    std::cout << std::endl;
}

void testPerspective(double fovy,double aspect,double zNear,double zFar)
{
    osg::Matrix f;
    f.makePerspective(fovy,aspect,zNear,zFar);

    double c_fovy=0;
    double c_aspect=0;
    double c_zNear=0;
    double c_zFar=0;

    std::cout << "testPerspective "<< f.getPerspective(c_fovy,c_aspect,c_zNear,c_zFar) << std::endl;
    std::cout << "  fovy = "<<fovy<<" compute "<<c_fovy<<std::endl;
    std::cout << "  aspect = "<<aspect<<" compute "<<c_aspect<<std::endl;

    std::cout << "  zNear = "<<zNear<<" compute "<<c_zNear<<std::endl;
    std::cout << "  zFar = "<<zFar<<" compute "<<c_zFar<<std::endl;

    std::cout << std::endl;
}

void testLookAt(const osg::Vec3& eye,const osg::Vec3& center,const osg::Vec3& up)
{
    osg::Matrix mv;
    mv.makeLookAt(eye,center,up);

    osg::Vec3 c_eye,c_center,c_up;
    mv.getLookAt(c_eye,c_center,c_up);

    std::cout << "testLookAt"<<std::endl;
    std::cout << "  eye "<<eye<< " compute "<<c_eye<<std::endl;
    std::cout << "  eye "<<center<< " compute "<<c_center<<std::endl;
    std::cout << "  eye "<<up<< " compute "<<c_up<<std::endl;

    std::cout << std::endl;

}

void sizeOfTest()
{
  std::cout<<"sizeof(bool)=="<<sizeof(bool)<<std::endl;
  std::cout<<"sizeof(char)=="<<sizeof(char)<<std::endl;
  std::cout<<"sizeof(short)=="<<sizeof(short)<<std::endl;
  std::cout<<"sizeof(int)=="<<sizeof(int)<<std::endl;
  std::cout<<"sizeof(long)=="<<sizeof(long)<<std::endl;
  std::cout<<"sizeof(long int)=="<<sizeof(long int)<<std::endl;

#if defined(_MSC_VER)
  // long long isn't supported on VS6.0...
  std::cout<<"sizeof(__int64)=="<<sizeof(__int64)<<std::endl;
#else
  std::cout<<"sizeof(long long)=="<<sizeof(long long)<<std::endl;
#endif
  std::cout<<"sizeof(float)=="<<sizeof(float)<<std::endl;
  std::cout<<"sizeof(double)=="<<sizeof(double)<<std::endl;
}

void testQuat()
{
    osg::Quat q1;
    q1.makeRotate(osg::DegreesToRadians(30.0),0.0f,0.0f,1.0f);

    osg::Quat q2;
    q2.makeRotate(osg::DegreesToRadians(133.0),0.0f,1.0f,1.0f);

    osg::Quat q1_2 = q1*q2;
    osg::Quat q2_1 = q2*q1;

    osg::Matrix m1 = osg::Matrix::rotate(q1);
    osg::Matrix m2 = osg::Matrix::rotate(q2);

    osg::Matrix m1_2 = m1*m2;
    osg::Matrix m2_1 = m2*m1;

    osg::Quat qm1_2;
    qm1_2.set(m1_2);

    osg::Quat qm2_1;
    qm2_1.set(m2_1);

    std::cout<<"q1*q2 = "<<q1_2<<std::endl;
    std::cout<<"q2*q1 = "<<q2_1<<std::endl;
    std::cout<<"m1*m2 = "<<qm1_2<<std::endl;
    std::cout<<"m2*m1 = "<<qm2_1<<std::endl;

}

int main( int argc, char** argv )
{
    osg::ArgumentParser arguments(&argc,argv);

    // set up the usage document, in case we need to print out how to use this program.
    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which runs units tests.");
    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options]");
    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
    arguments.getApplicationUsage()->addCommandLineOption("qt","Display qualified tests.");
    arguments.getApplicationUsage()->addCommandLineOption("sizeof","Display sizeof tests.");
    arguments.getApplicationUsage()->addCommandLineOption("matrix","Display qualified tests.");

    if (arguments.argc()<=1)
    {
        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
        return 1;
    }

    bool printQualifiedTest = false;
    while (arguments.read("qt")) printQualifiedTest = true;

    bool printMatrixTest = false;
    while (arguments.read("matrix")) printMatrixTest = true;

    bool printSizeOfTest = false;
    while (arguments.read("sizeof")) printSizeOfTest = true;

    bool printQuatTest = false;
    while (arguments.read("quat")) printQuatTest = true;

    // if user request help write it out to cout.
    if (arguments.read("-h") || arguments.read("--help"))
    {
        std::cout<<arguments.getApplicationUsage()->getCommandLineUsage()<<std::endl;
        arguments.getApplicationUsage()->write(std::cout,arguments.getApplicationUsage()->getCommandLineOptions());
        return 1;
    }

    // any option left unread are converted into errors to write out later.
    arguments.reportRemainingOptionsAsUnrecognized();

    // report any errors if they have occured when parsing the program aguments.
    if (arguments.errors())
    {
        arguments.writeErrorMessages(std::cout);
        return 1;
    }

    if (printQuatTest)
    {
        testQuat();
    }

    if (printMatrixTest)
    {
        std::cout<<"******   Running matrix tests   ******"<<std::endl;

        testFrustum(-1,1,-1,1,1,1000);
        testFrustum(0,1,1,2,2.5,100000);

        testOrtho(0,1,1,2,2.1,1000);
        testOrtho(-1,10,1,20,2.5,100000);

        testPerspective(20,1,1,1000);
        testPerspective(90,2,1,1000);

        testLookAt(osg::Vec3(10.0,4.0,2.0),osg::Vec3(10.0,4.0,2.0)+osg::Vec3(0.0,1.0,0.0),osg::Vec3(0.0,0.0,1.0));
        testLookAt(osg::Vec3(10.0,4.0,2.0),osg::Vec3(10.0,4.0,2.0)+osg::Vec3(1.0,1.0,0.0),osg::Vec3(0.0,0.0,1.0));

    }

    if (printSizeOfTest)
    {
        std::cout<<"**** sizeof() tests  ******"<<std::endl;

        sizeOfTest();

        std::cout<<std::endl;
    }

    if (printQualifiedTest)
    {
         std::cout<<"*****   Qualified Tests  ******"<<std::endl;

         osgUtx::QualifiedTestPrinter printer;
         osgUtx::TestGraph::instance().root()->accept( printer );
         std::cout<<std::endl;
    }

    std::cout<<"******   Running tests   ******"<<std::endl;

    // Global Data or Context
    osgUtx::TestContext ctx;
    osgUtx::TestRunner runner( ctx );
    runner.specify("root");

    osgUtx::TestGraph::instance().root()->accept( runner );

    return 0;
}
<|endoftext|>