text:
@glfunc glGetNamedFramebufferParameterivEXT(framebuffer::GLuint, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glDrawElementsInstancedBaseVertexBaseInstance(mode::GLenum, count::GLsizei, type_::GLenum, indices::Ptr{Void}, instancecount::GLsizei, basevertex::GLint, baseinstance::GLuint)::Void
@glfunc glReadBuffer(mode::GLenum)::Void
@glfunc glBindBufferBase(target::GLenum, index::GLuint, buffer::GLuint)::Void
@glfunc glClientWaitSync(sync::GLsync, flags::GLbitfield, timeout::GLuint64)::GLenum
@glfunc glGetIntegeri_v(target::GLenum, index::GLuint, data::Ptr{GLint})::Void
@glfunc glTexCoordP2ui(type_::GLenum, coords::GLuint)::Void
@glfunc glTexParameterIiv(target::GLenum, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glVertexAttribI2iv(index::GLuint, v::Ptr{GLint})::Void
@glfunc glProgramUniformMatrix4fv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glSamplerParameteri(sampler::GLuint, pname::GLenum, param::GLint)::Void
@glfunc glStencilFuncSeparate(face::GLenum, func_::GLenum, ref::GLint, mask::GLuint)::Void
@glfunc glResumeTransformFeedback()::Void
@glfunc glProgramUniform1fv(program::GLuint, location::GLint, count::GLsizei, value::Ptr{GLfloat})::Void
@glfunc glProgramUniform3uiv(program::GLuint, location::GLint, count::GLsizei, value::Ptr{GLuint})::Void
@glfunc glUniform1d(location::GLint, x::GLdouble)::Void
@glfunc glUniformMatrix2x4dv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glFinish()::Void
@glfunc glProgramUniformMatrix2x3fv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glClear(mask::GLbitfield)::Void
@glfunc glBindTransformFeedback(target::GLenum, id::GLuint)::Void
@glfunc glShaderSource(shader::GLuint, count::GLsizei, string_::Ptr{Ptr{GLchar}}, length::Ptr{GLint})::Void
@glfunc glUniform2iv(location::GLint, count::GLsizei, value::Ptr{GLint})::Void
@glfunc glBindTexture(target::GLenum, texture::GLuint)::Void
@glfunc glDrawElementsIndirect(mode::GLenum, type_::GLenum, indirect::Ptr{Void})::Void
@glfunc glUniformMatrix3dv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glGetSamplerParameterIiv(sampler::GLuint, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glGetPointerv(pname::GLenum, params::Ptr{Ptr{Void}})::Void
@glfunc glReleaseShaderCompiler()::Void
@glfunc glGetQueryObjectui64v(id::GLuint, pname::GLenum, params::Ptr{GLuint64})::Void
@glfunc glVertexAttribDivisor(index::GLuint, divisor::GLuint)::Void
@glfunc glVertexAttribP4ui(index::GLuint, type_::GLenum, normalized::GLboolean, value::GLuint)::Void
@glfunc glDeleteProgram(program::GLuint)::Void
@glfunc glSamplerParameterIuiv(sampler::GLuint, pname::GLenum, param::Ptr{GLuint})::Void
@glfunc glGetProgramiv(program::GLuint, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glUniform3dv(location::GLint, count::GLsizei, value::Ptr{GLdouble})::Void
@glfunc glProgramUniform4fv(program::GLuint, location::GLint, count::GLsizei, value::Ptr{GLfloat})::Void
@glfunc glDrawTransformFeedbackInstanced(mode::GLenum, id::GLuint, instancecount::GLsizei)::Void
@glfunc glScissorArrayv(first::GLuint, count::GLsizei, v::Ptr{GLint})::Void
@glfunc glGenerateMipmap(target::GLenum)::Void
@glfunc glProgramUniform2dv(program::GLuint, location::GLint, count::GLsizei, value::Ptr{GLdouble})::Void
@glfunc glUniform4d(location::GLint, x::GLdouble, y::GLdouble, z::GLdouble, w::GLdouble)::Void
@glfunc glDeleteRenderbuffers(n::GLsizei, renderbuffers::Ptr{GLuint})::Void
@glfunc glPopDebugGroup()::Void
@glfunc glGetShaderSource(shader::GLuint, bufSize::GLsizei, length::Ptr{GLsizei}, source::Ptr{GLchar})::Void
@glfunc glIsBuffer(buffer::GLuint)::Bool
@glfunc glGetAttachedShaders(program::GLuint, maxCount::GLsizei, count::Ptr{GLsizei}, obj::Ptr{GLuint})::Void
@glfunc glVertexAttribI1uiv(index::GLuint, v::Ptr{GLuint})::Void
@glfunc glMultiTexCoordP1ui(texture::GLenum, type_::GLenum, coords::GLuint)::Void
@glfunc glTextureView(texture::GLuint, target::GLenum, origtexture::GLuint, internalformat::GLenum, minlevel::GLuint, numlevels::GLuint, minlayer::GLuint, numlayers::GLuint)::Void
@glfunc glProgramUniform4uiv(program::GLuint, location::GLint, count::GLsizei, value::Ptr{GLuint})::Void
@glfunc glSecondaryColorP3uiv(type_::GLenum, color::Ptr{GLuint})::Void
@glfunc glQueryCounter(id::GLuint, target::GLenum)::Void
@glfunc glTexStorage3DMultisample(target::GLenum, samples::GLsizei, internalformat::GLenum, width::GLsizei, height::GLsizei, depth::GLsizei, fixedsamplelocations::GLboolean)::Void
@glfunc glDrawArraysIndirect(mode::GLenum, indirect::Ptr{Void})::Void
@glfunc glUniform4ui(location::GLint, v0::GLuint, v1::GLuint, v2::GLuint, v3::GLuint)::Void
@glfunc glProgramUniform4f(program::GLuint, location::GLint, v0::GLfloat, v1::GLfloat, v2::GLfloat, v3::GLfloat)::Void
@glfunc glCompressedTexSubImage1D(target::GLenum, level::GLint, xoffset::GLint, width::GLsizei, format::GLenum, imageSize::GLsizei, data::Ptr{Void})::Void
@glfunc glProgramUniformMatrix2dv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glTexParameterf(target::GLenum, pname::GLenum, param::GLfloat)::Void
@glfunc glShaderBinary(count::GLsizei, shaders::Ptr{GLuint}, binaryformat::GLenum, binary::Ptr{Void}, length::GLsizei)::Void
@glfunc glPauseTransformFeedback()::Void
@glfunc glMultiDrawElements(mode::GLenum, count::Ptr{GLsizei}, type_::GLenum, indices::Ptr{Ptr{Void}}, drawcount::GLsizei)::Void
@glfunc glGetBufferPointerv(target::GLenum, pname::GLenum, params::Ptr{Ptr{Void}})::Void
@glfunc glVertexAttribP4uiv(index::GLuint, type_::GLenum, normalized::GLboolean, value::Ptr{GLuint})::Void
@glfunc glVertexArrayVertexAttribIFormatEXT(vaobj::GLuint, attribindex::GLuint, size::GLint, type_::GLenum, relativeoffset::GLuint)::Void
@glfunc glEndConditionalRender()::Void
@glfunc glFlush()::Void
@glfunc glBlendFuncSeparatei(buf::GLuint, srcRGB::GLenum, dstRGB::GLenum, srcAlpha::GLenum, dstAlpha::GLenum)::Void
@glfunc glProgramUniform1dv(program::GLuint, location::GLint, count::GLsizei, value::Ptr{GLdouble})::Void
@glfunc glProgramUniform2ui(program::GLuint, location::GLint, v0::GLuint, v1::GLuint)::Void
@glfunc glActiveTexture(texture::GLenum)::Void
@glfunc glSecondaryColorP3ui(type_::GLenum, color::GLuint)::Void
@glfunc glProgramUniformMatrix3dv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glBlendEquationi(buf::GLuint, mode::GLenum)::Void
@glfunc glPolygonOffset(factor::GLfloat, units::GLfloat)::Void
@glfunc glDetachShader(program::GLuint, shader::GLuint)::Void
@glfunc glUniform4uiv(location::GLint, count::GLsizei, value::Ptr{GLuint})::Void
@glfunc glTexParameteriv(target::GLenum, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glGetIntegerv(pname::GLenum, params::Ptr{GLint})::Void
@glfunc glEnable(cap::GLenum)::Void
@glfunc glClearBufferData(target::GLenum, internalformat::GLenum, format::GLenum, type_::GLenum, data::Ptr{Void})::Void
@glfunc glMapBufferRange(target::GLenum, offset::GLintptr, length::GLsizeiptr, access::GLbitfield)::Ptr{Void}
@glfunc glTexCoordP4uiv(type_::GLenum, coords::Ptr{GLuint})::Void
@glfunc glDepthRangeArrayv(first::GLuint, count::GLsizei, v::Ptr{GLdouble})::Void
@glfunc glGetCompressedTexImage(target::GLenum, level::GLint, img::Ptr{Void})::Void
@glfunc glProgramUniformMatrix4x2fv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glIsTransformFeedback(id::GLuint)::Bool
@glfunc glMultiTexCoordP1uiv(texture::GLenum, type_::GLenum, coords::Ptr{GLuint})::Void
@glfunc glSamplerParameterIiv(sampler::GLuint, pname::GLenum, param::Ptr{GLint})::Void
@glfunc glProgramUniform2i(program::GLuint, location::GLint, v0::GLint, v1::GLint)::Void
@glfunc glUniform4dv(location::GLint, count::GLsizei, value::Ptr{GLdouble})::Void
@glfunc glGetDoublev(pname::GLenum, params::Ptr{GLdouble})::Void
@glfunc glTexCoordP1uiv(type_::GLenum, coords::Ptr{GLuint})::Void
@glfunc glProgramUniform1f(program::GLuint, location::GLint, v0::GLfloat)::Void
@glfunc glTexParameterIuiv(target::GLenum, pname::GLenum, params::Ptr{GLuint})::Void
@glfunc glUniformMatrix2x3dv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glPixelStorei(pname::GLenum, param::GLint)::Void
@glfunc glUniform3ui(location::GLint, v0::GLuint, v1::GLuint, v2::GLuint)::Void
@glfunc glGetTexParameterIuiv(target::GLenum, pname::GLenum, params::Ptr{GLuint})::Void
@glfunc glGetShaderiv(shader::GLuint, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glTexCoordP4ui(type_::GLenum, coords::GLuint)::Void
@glfunc glPointParameteri(pname::GLenum, param::GLint)::Void
@glfunc glTextureStorage1DEXT(texture::GLuint, target::GLenum, levels::GLsizei, internalformat::GLenum, width::GLsizei)::Void
@glfunc glEnablei(target::GLenum, index::GLuint)::Void
@glfunc glTexCoordP3uiv(type_::GLenum, coords::Ptr{GLuint})::Void
@glfunc glGetRenderbufferParameteriv(target::GLenum, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glVertexAttribI4sv(index::GLuint, v::Ptr{GLshort})::Void
@glfunc glGetActiveSubroutineName(program::GLuint, shadertype::GLenum, index::GLuint, bufsize::GLsizei, length::Ptr{GLsizei}, name::Ptr{GLchar})::Void
@glfunc glCompileShader(shader::GLuint)::Void
@glfunc glLinkProgram(program::GLuint)::Void
@glfunc glReadPixels(x::GLint, y::GLint, width::GLsizei, height::GLsizei, format::GLenum, type_::GLenum, pixels::Ptr{Void})::Void
@glfunc glCreateShaderProgramv(type_::GLenum, count::GLsizei, strings::Ptr{GLchar})::GLuint
@glfunc glBufferData(target::GLenum, size::GLsizeiptr, data::Ptr{Void}, usage::GLenum)::Void
@glfunc glPointParameteriv(pname::GLenum, params::Ptr{GLint})::Void
@glfunc glUniform2fv(location::GLint, count::GLsizei, value::Ptr{GLfloat})::Void
@glfunc glDrawTransformFeedbackStream(mode::GLenum, id::GLuint, stream::GLuint)::Void
@glfunc glUniform2dv(location::GLint, count::GLsizei, value::Ptr{GLdouble})::Void
@glfunc glTexSubImage1D(target::GLenum, level::GLint, xoffset::GLint, width::GLsizei, format::GLenum, type_::GLenum, pixels::Ptr{Void})::Void
@glfunc glDispatchCompute(num_groups_x::GLuint, num_groups_y::GLuint, num_groups_z::GLuint)::Void
@glfunc glGetBufferSubData(target::GLenum, offset::GLintptr, size::GLsizeiptr, data::Ptr{Void})::Void
@glfunc glVertexP2uiv(type_::GLenum, value::Ptr{GLuint})::Void
@glfunc glUniform4fv(location::GLint, count::GLsizei, value::Ptr{GLfloat})::Void
@glfunc glGetProgramResourceLocation(program::GLuint, programCinterface::GLenum, name::Ptr{GLchar})::GLint
@glfunc glVertexArrayVertexAttribLFormatEXT(vaobj::GLuint, attribindex::GLuint, size::GLint, type_::GLenum, relativeoffset::GLuint)::Void
@glfunc glGetUniformuiv(program::GLuint, location::GLint, params::Ptr{GLuint})::Void
@glfunc glBindImageTexture(unit::GLuint, texture::GLuint, level::GLint, layered::GLboolean, layer::GLint, access::GLenum, format::GLenum)::Void
@glfunc glVertexAttribL4dv(index::GLuint, v::Ptr{GLdouble})::Void
@glfunc glColorP4ui(type_::GLenum, color::GLuint)::Void
@glfunc glUniform2f(location::GLint, v0::GLfloat, v1::GLfloat)::Void
@glfunc glColorP4uiv(type_::GLenum, color::Ptr{GLuint})::Void
@glfunc glVertexAttribIPointer(index::GLuint, size::GLint, type_::GLenum, stride::GLsizei, pointer::Ptr{Void})::Void
@glfunc glGetProgramPipelineiv(pipeline::GLuint, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glMultiTexCoordP3uiv(texture::GLenum, type_::GLenum, coords::Ptr{GLuint})::Void
@glfunc glGetProgramResourceName(program::GLuint, programInterface::GLenum, index::GLuint, bufSize::GLsizei, length::Ptr{GLsizei}, name::Ptr{GLchar})::Void
@glfunc glVertexP4ui(type_::GLenum, value::GLuint)::Void
@glfunc glFrontFace(mode::GLenum)::Void
@glfunc glProgramUniform4i(program::GLuint, location::GLint, v0::GLint, v1::GLint, v2::GLint, v3::GLint)::Void
@glfunc glPointParameterfv(pname::GLenum, params::Ptr{GLfloat})::Void
@glfunc glShaderStorageBlockBinding(program::GLuint, storageBlockIndex::GLuint, storageBlockBinding::GLuint)::Void
@glfunc glClearStencil(s::GLint)::Void
@glfunc glBlendEquation(mode::GLenum)::Void
@glfunc glIsProgramPipeline(pipeline::GLuint)::Bool
@glfunc glUniform3f(location::GLint, v0::GLfloat, v1::GLfloat, v2::GLfloat)::Void
@glfunc glVertexAttribI4usv(index::GLuint, v::Ptr{GLushort})::Void
@glfunc glFramebufferParameteri(target::GLenum, pname::GLenum, param::GLint)::Void
@glfunc glGenSamplers(count::GLsizei, samplers::Ptr{GLuint})::Void
@glfunc glUniformMatrix4fv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glBlendColor(red::GLfloat, green::GLfloat, blue::GLfloat, alpha::GLfloat)::Void
@glfunc glInvalidateTexImage(texture::GLuint, level::GLint)::Void
@glfunc glGetSubroutineIndex(program::GLuint, shadertype::GLenum, name::Ptr{GLchar})::GLuint
@glfunc glVertexAttribL3dv(index::GLuint, v::Ptr{GLdouble})::Void
@glfunc glProgramUniformMatrix2fv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glDrawElementsInstancedBaseInstance(mode::GLenum, count::GLsizei, type_::GLenum, indices::Ptr{Void}, instancecount::GLsizei, baseinstance::GLuint)::Void
@glfunc glIndexub(c::GLubyte)::Void
@glfunc glGenRenderbuffers(n::GLsizei, renderbuffers::Ptr{GLuint})::Void
@glfunc glProgramUniform4dv(program::GLuint, location::GLint, count::GLsizei, value::Ptr{GLdouble})::Void
@glfunc glProgramUniformMatrix2x3dv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glTexImage3D(target::GLenum, level::GLint, internalformat::GLint, width::GLsizei, height::GLsizei, depth::GLsizei, border::GLint, format::GLenum, type_::GLenum, pixels::Ptr{Void})::Void
@glfunc glGetVertexAttribfv(index::GLuint, pname::GLenum, params::Ptr{GLfloat})::Void
@glfunc glVertexAttribL4d(index::GLuint, x::GLdouble, y::GLdouble, z::GLdouble, w::GLdouble)::Void
@glfunc glBindFramebuffer(target::GLenum, framebuffer::GLuint)::Void
@glfunc glFramebufferTexture3D(target::GLenum, attachment::GLenum, textarget::GLenum, texture::GLuint, level::GLint, zoffset::GLint)::Void
@glfunc glVertexArrayVertexAttribFormatEXT(vaobj::GLuint, attribindex::GLuint, size::GLint, type_::GLenum, normalized::GLboolean, relativeoffset::GLuint)::Void
@glfunc glGetVertexAttribLdv(index::GLuint, pname::GLenum, params::Ptr{GLdouble})::Void
@glfunc glVertexAttribBinding(attribindex::GLuint, bindingindex::GLuint)::Void
@glfunc glUniformMatrix3fv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glUniformMatrix4dv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glProgramUniformMatrix4x3dv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glProgramUniformMatrix3x4fv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glGetDebugMessageLog(count::GLuint, bufsize::GLsizei, sources::Ptr{GLenum}, types::Ptr{GLenum}, ids::Ptr{GLuint}, severities::Ptr{GLenum}, lengths::Ptr{GLsizei}, messageLog::Ptr{GLchar})::GLuint
@glfunc glGetVertexAttribiv(index::GLuint, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glDebugMessageInsert(source::GLenum, type_::GLenum, id::GLuint, severity::GLenum, length::GLsizei, buf::Ptr{GLchar})::Void
@glfunc glNormalP3ui(type_::GLenum, coords::GLuint)::Void
@glfunc glDrawArraysInstanced(mode::GLenum, first::GLint, count::GLsizei, instancecount::GLsizei)::Void
@glfunc glCompressedTexImage2D(target::GLenum, level::GLint, internalformat::GLenum, width::GLsizei, height::GLsizei, border::GLint, imageSize::GLsizei, data::Ptr{Void})::Void
@glfunc glPushDebugGroup(source::GLenum, id::GLuint, length::GLsizei, message::Ptr{GLchar})::Void
@glfunc glGetUniformBlockIndex(program::GLuint, uniformBlockName::Ptr{GLchar})::GLuint
@glfunc glInvalidateFramebuffer(target::GLenum, numAttachments::GLsizei, attachments::Ptr{GLenum})::Void
@glfunc glVertexAttribP2uiv(index::GLuint, type_::GLenum, normalized::GLboolean, value::Ptr{GLuint})::Void
@glfunc glIsEnabledi(target::GLenum, index::GLuint)::Bool
@glfunc glVertexAttribP2ui(index::GLuint, type_::GLenum, normalized::GLboolean, value::GLuint)::Void
@glfunc glDrawArrays(mode::GLenum, first::GLint, count::GLsizei)::Void
@glfunc glGetActiveAttrib(program::GLuint, index::GLuint, bufSize::GLsizei, length::Ptr{GLsizei}, size::Ptr{GLint}, type_::Ptr{GLenum}, name::Ptr{GLchar})::Void
@glfunc glCopyTexImage1D(target::GLenum, level::GLint, internalformat::GLenum, x::GLint, y::GLint, width::GLsizei, border::GLint)::Void
@glfunc glProgramUniform2f(program::GLuint, location::GLint, v0::GLfloat, v1::GLfloat)::Void
@glfunc glCopyImageSubData(srcName::GLuint, srcTarget::GLenum, srcLevel::GLint, srcX::GLint, srcY::GLint, srcZ::GLint, dstName::GLuint, dstTarget::GLenum, dstLevel::GLint, dstX::GLint, dstY::GLint, dstZ::GLint, srcWidth::GLsizei, srcHeight::GLsizei, srcDepth::GLsizei)::Void
@glfunc glGetError()::GLenum
@glfunc glNormalP3uiv(type_::GLenum, coords::Ptr{GLuint})::Void
@glfunc glTexStorage2D(target::GLenum, levels::GLsizei, internalformat::GLenum, width::GLsizei, height::GLsizei)::Void
@glfunc glProgramUniformMatrix4x3fv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glDrawRangeElementsBaseVertex(mode::GLenum, start::GLuint, END::GLuint, count::GLsizei, type_::GLenum, indices::Ptr{Void}, basevertex::GLint)::Void
@glfunc glGenProgramPipelines(n::GLsizei, pipelines::Ptr{GLuint})::Void
@glfunc glVertexAttribI4uiv(index::GLuint, v::Ptr{GLuint})::Void
@glfunc glActiveShaderProgram(pipeline::GLuint, program::GLuint)::Void
@glfunc glGetInteger64v(pname::GLenum, params::Ptr{GLint64})::Void
@glfunc glPrimitiveRestartIndex(index::GLuint)::Void
@glfunc glDeleteShader(shader::GLuint)::Void
@glfunc glGenBuffers(n::GLsizei, buffers::Ptr{GLuint})::Void
@glfunc glTexParameterfv(target::GLenum, pname::GLenum, params::Ptr{GLfloat})::Void
@glfunc glGetSamplerParameteriv(sampler::GLuint, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glProgramUniform3d(program::GLuint, location::GLint, v0::GLdouble, v1::GLdouble, v2::GLdouble)::Void
@glfunc glVertexAttribI1iv(index::GLuint, v::Ptr{GLint})::Void
@glfunc glUniform2uiv(location::GLint, count::GLsizei, value::Ptr{GLuint})::Void
@glfunc glUniform1i(location::GLint, v0::GLint)::Void
@glfunc glUniform3uiv(location::GLint, count::GLsizei, value::Ptr{GLuint})::Void
@glfunc glProgramUniform1uiv(program::GLuint, location::GLint, count::GLsizei, value::Ptr{GLuint})::Void
@glfunc glUniform1iv(location::GLint, count::GLsizei, value::Ptr{GLint})::Void
@glfunc glUniform1fv(location::GLint, count::GLsizei, value::Ptr{GLfloat})::Void
@glfunc glScissorIndexedv(index::GLuint, v::Ptr{GLint})::Void
@glfunc glIsTexture(texture::GLuint)::Bool
@glfunc glDrawArraysInstancedBaseInstance(mode::GLenum, first::GLint, count::GLsizei, instancecount::GLsizei, baseinstance::GLuint)::Void
@glfunc glVertexAttribI1i(index::GLuint, x::GLint)::Void
@glfunc glVertexAttribI3ui(index::GLuint, x::GLuint, y::GLuint, z::GLuint)::Void
@glfunc glGetActiveUniformBlockiv(program::GLuint, uniformBlockIndex::GLuint, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glVertexAttribI3i(index::GLuint, x::GLint, y::GLint, z::GLint)::Void
@glfunc glBlendFunci(buf::GLuint, src::GLenum, dst::GLenum)::Void
@glfunc glGetVertexAttribdv(index::GLuint, pname::GLenum, params::Ptr{GLdouble})::Void
@glfunc glBlendEquationSeparate(modeRGB::GLenum, modeAlpha::GLenum)::Void
@glfunc glFenceSync(condition::GLenum, flags::GLbitfield)::GLsync
@glfunc glSamplerParameterfv(sampler::GLuint, pname::GLenum, param::Ptr{GLfloat})::Void
@glfunc glIsShader(shader::GLuint)::Bool
@glfunc glProgramUniform3f(program::GLuint, location::GLint, v0::GLfloat, v1::GLfloat, v2::GLfloat)::Void
@glfunc glUniformMatrix4x3fv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glGetQueryObjectuiv(id::GLuint, pname::GLenum, params::Ptr{GLuint})::Void
@glfunc glPointParameterf(pname::GLenum, param::GLfloat)::Void
@glfunc glIndexubv(c::Ptr{GLubyte})::Void
@glfunc glClearBufferiv(buffer::GLenum, drawbuffer::GLint, value::Ptr{GLint})::Void
@glfunc glBindVertexArray(array::GLuint)::Void
@glfunc glGetInternalformati64v(target::GLenum, internalformat::GLenum, pname::GLenum, bufSize::GLsizei, params::Ptr{GLint64})::Void
@glfunc glVertexP4uiv(type_::GLenum, value::Ptr{GLuint})::Void
@glfunc glVertexAttribI2uiv(index::GLuint, v::Ptr{GLuint})::Void
@glfunc glGetProgramResourceiv(program::GLuint, programInterface::GLenum, index::GLuint, propCount::GLsizei, props::Ptr{GLenum}, bufSize::GLsizei, length::Ptr{GLsizei}, params::Ptr{GLint})::Void
@glfunc glViewport(x::GLint, y::GLint, width::GLsizei, height::GLsizei)::Void
@glfunc glTexImage1D(target::GLenum, level::GLint, internalformat::GLint, width::GLsizei, border::GLint, format::GLenum, type_::GLenum, pixels::Ptr{Void})::Void
@glfunc glUniform1uiv(location::GLint, count::GLsizei, value::Ptr{GLuint})::Void
@glfunc glProgramUniform4ui(program::GLuint, location::GLint, v0::GLuint, v1::GLuint, v2::GLuint, v3::GLuint)::Void
@glfunc glUniform1f(location::GLint, v0::GLfloat)::Void
@glfunc glVertexAttribP3uiv(index::GLuint, type_::GLenum, normalized::GLboolean, value::Ptr{GLuint})::Void
@glfunc glBeginQuery(target::GLenum, id::GLuint)::Void
@glfunc glMultiDrawArrays(mode::GLenum, first::Ptr{GLint}, count::Ptr{GLsizei}, drawcount::GLsizei)::Void
@glfunc glDrawBuffer(mode::GLenum)::Void
@glfunc glLogicOp(opcode::GLenum)::Void
@glfunc glObjectLabel(identifier::GLenum, name::GLuint, length::GLsizei, label::Ptr{GLchar})::Void
@glfunc glUniformMatrix3x2dv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glUniform3d(location::GLint, x::GLdouble, y::GLdouble, z::GLdouble)::Void
@glfunc glDepthRangeIndexed(index::GLuint, n::GLdouble, f::GLdouble)::Void
@glfunc glGetProgramBinary(program::GLuint, bufSize::GLsizei, length::Ptr{GLsizei}, binaryFormat::Ptr{GLenum}, binary::Ptr{Void})::Void
@glfunc glPointSize(size::GLfloat)::Void
@glfunc glGetUniformfv(program::GLuint, location::GLint, params::Ptr{GLfloat})::Void
@glfunc glClearBufferfv(buffer::GLenum, drawbuffer::GLint, value::Ptr{GLfloat})::Void
@glfunc glCopyTexSubImage1D(target::GLenum, level::GLint, xoffset::GLint, x::GLint, y::GLint, width::GLsizei)::Void
@glfunc glIsEnabled(cap::GLenum)::Bool
@glfunc glCreateShader(type_::GLenum)::GLuint
@glfunc glTextureStorage2DEXT(texture::GLuint, target::GLenum, levels::GLsizei, internalformat::GLenum, width::GLsizei, height::GLsizei)::Void
@glfunc glPixelStoref(pname::GLenum, param::GLfloat)::Void
@glfunc glGetMultisamplefv(pname::GLenum, index::GLuint, val::Ptr{GLfloat})::Void
@glfunc glGetFragDataIndex(program::GLuint, name::Ptr{GLchar})::GLint
@glfunc glGetUniformIndices(program::GLuint, uniformCount::GLsizei, uniformNames::Ptr{Ptr{GLchar}}, uniformIndices::Ptr{GLuint})::Void
@glfunc glUniform1dv(location::GLint, count::GLsizei, value::Ptr{GLdouble})::Void
@glfunc glGetFragDataLocation(program::GLuint, name::Ptr{GLchar})::GLint
@glfunc glMultiTexCoordP2ui(texture::GLenum, type_::GLenum, coords::GLuint)::Void
@glfunc glDepthFunc(func_::GLenum)::Void
@glfunc glVertexAttribI4iv(index::GLuint, v::Ptr{GLint})::Void
@glfunc glUniformMatrix2x4fv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glBufferSubData(target::GLenum, offset::GLintptr, size::GLsizeiptr, data::Ptr{Void})::Void
@glfunc glUniformMatrix3x4fv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glBindBufferRange(target::GLenum, index::GLuint, buffer::GLuint, offset::GLintptr, size::GLsizeiptr)::Void
@glfunc glGenQueries(n::GLsizei, ids::Ptr{GLuint})::Void
@glfunc glDebugMessageCallback(callback::Ptr{Void}, userParam::Ptr{Void})::Void
@glfunc glDebugMessageCallbackARB(callback::Ptr{Void}, userParam::Ptr{Void})::Void
@glfunc glInvalidateTexSubImage(texture::GLuint, level::GLint, xoffset::GLint, yoffset::GLint, zoffset::GLint, width::GLsizei, height::GLsizei, depth::GLsizei)::Void
@glfunc glColorP3uiv(type_::GLenum, color::Ptr{GLuint})::Void
@glfunc glTexStorage1D(target::GLenum, levels::GLsizei, internalformat::GLenum, width::GLsizei)::Void
@glfunc glBlendFunc(sfactor::GLenum, dfactor::GLenum)::Void
@glfunc glGetBooleanv(pname::GLenum, params::Ptr{GLboolean})::Void
@glfunc glUniformMatrix3x4dv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glGetObjectLabel(identifier::GLenum, name::GLuint, bufSize::GLsizei, length::Ptr{GLsizei}, label::Ptr{GLchar})::Void
@glfunc glSampleCoverage(value::GLfloat, invert::GLboolean)::Void
@glfunc glProgramUniformMatrix3x2fv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glVertexAttribL2dv(index::GLuint, v::Ptr{GLdouble})::Void
@glfunc glGetFloatv(pname::GLenum, params::Ptr{GLfloat})::Void
@glfunc glProvokingVertex(mode::GLenum)::Void
@glfunc glVertexAttribL3d(index::GLuint, x::GLdouble, y::GLdouble, z::GLdouble)::Void
@glfunc glClearDepth(depth::GLdouble)::Void
@glfunc glInvalidateBufferData(buffer::GLuint)::Void
@glfunc glProgramParameteri(program::GLuint, pname::GLenum, value::GLint)::Void
@glfunc glUniformMatrix3x2fv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glDisable(cap::GLenum)::Void
@glfunc glMultiDrawElementsIndirect(mode::GLenum, type_::GLenum, indirect::Ptr{Void}, drawcount::GLsizei, stride::GLsizei)::Void
@glfunc glMultiDrawElementsBaseVertex(mode::GLenum, count::Ptr{GLsizei}, type_::GLenum, indices::Ptr{Ptr{Void}}, drawcount::GLsizei, basevertex::Ptr{GLint})::Void
@glfunc glFlushMappedBufferRange(target::GLenum, offset::GLintptr, length::GLsizeiptr)::Void
@glfunc glGetUniformdv(program::GLuint, location::GLint, params::Ptr{GLdouble})::Void
@glfunc glGetProgramInterfaceiv(program::GLuint, programInterface::GLenum, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glTransformFeedbackVaryings(program::GLuint, count::GLsizei, varyings::Ptr{Ptr{GLchar}}, bufferMode::GLenum)::Void
@glfunc glGetVertexAttribIuiv(index::GLuint, pname::GLenum, params::Ptr{GLuint})::Void
@glfunc glGetShaderInfoLog(shader::GLuint, bufSize::GLsizei, length::Ptr{GLsizei}, infoLog::Ptr{GLchar})::Void
@glfunc glRenderbufferStorageMultisample(target::GLenum, samples::GLsizei, internalformat::GLenum, width::GLsizei, height::GLsizei)::Void
@glfunc glUniformMatrix2x3fv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glUseProgramStages(pipeline::GLuint, stages::GLbitfield, program::GLuint)::Void
@glfunc glVertexAttribLFormat(attribindex::GLuint, size::GLint, type_::GLenum, relativeoffset::GLuint)::Void
@glfunc glProgramUniform1i(program::GLuint, location::GLint, v0::GLint)::Void
@glfunc glGetFramebufferParameteriv(target::GLenum, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glDeleteProgramPipelines(n::GLsizei, pipelines::Ptr{GLuint})::Void
@glfunc glProgramUniform2fv(program::GLuint, location::GLint, count::GLsizei, value::Ptr{GLfloat})::Void
@glfunc glProgramUniform1iv(program::GLuint, location::GLint, count::GLsizei, value::Ptr{GLint})::Void
@glfunc glBindBuffer(target::GLenum, buffer::GLuint)::Void
@glfunc glGetAttribLocation(program::GLuint, name::Ptr{GLchar})::GLint
@glfunc glProgramUniform3ui(program::GLuint, location::GLint, v0::GLuint, v1::GLuint, v2::GLuint)::Void
@glfunc glTexParameteri(target::GLenum, pname::GLenum, param::GLint)::Void
@glfunc glWaitSync(sync::GLsync, flags::GLbitfield, timeout::GLuint64)::Void
@glfunc glTextureStorage3DMultisampleEXT(texture::GLuint, target::GLenum, samples::GLsizei, internalformat::GLenum, width::GLsizei, height::GLsizei, depth::GLsizei, fixedsamplelocations::GLboolean)::Void
@glfunc glIsVertexArray(array::GLuint)::Bool
@glfunc glEnableVertexAttribArray(index::GLuint)::Void
@glfunc glObjectPtrLabel(ptr::Ptr{Void}, length::GLsizei, label::Ptr{GLchar})::Void
@glfunc glProgramBinary(program::GLuint, binaryFormat::GLenum, binary::Ptr{Void}, length::GLsizei)::Void
@glfunc glCompressedTexImage1D(target::GLenum, level::GLint, internalformat::GLenum, width::GLsizei, border::GLint, imageSize::GLsizei, data::Ptr{Void})::Void
@glfunc glTexCoordP2uiv(type_::GLenum, coords::Ptr{GLuint})::Void
@glfunc glUseProgram(program::GLuint)::Void
@glfunc glProgramUniform3i(program::GLuint, location::GLint, v0::GLint, v1::GLint, v2::GLint)::Void
@glfunc glVertexAttribI2ui(index::GLuint, x::GLuint, y::GLuint)::Void
@glfunc glGetActiveSubroutineUniformiv(program::GLuint, shadertype::GLenum, index::GLuint, pname::GLenum, values::Ptr{GLint})::Void
@glfunc glDepthMask(flag::GLboolean)::Void
@glfunc glPolygonMode(face::GLenum, mode::GLenum)::Void
@glfunc glVertexAttribI3uiv(index::GLuint, v::Ptr{GLuint})::Void
@glfunc glFramebufferTexture1D(target::GLenum, attachment::GLenum, textarget::GLenum, texture::GLuint, level::GLint)::Void
@glfunc glGetActiveSubroutineUniformName(program::GLuint, shadertype::GLenum, index::GLuint, bufsize::GLsizei, length::Ptr{GLsizei}, name::Ptr{GLchar})::Void
@glfunc glGenFramebuffers(n::GLsizei, framebuffers::Ptr{GLuint})::Void
@glfunc glFramebufferTextureLayer(target::GLenum, attachment::GLenum, texture::GLuint, level::GLint, layer::GLint)::Void
@glfunc glViewportArrayv(first::GLuint, count::GLsizei, v::Ptr{GLfloat})::Void
@glfunc glDrawRangeElements(mode::GLenum, start::GLuint, END::GLuint, count::GLsizei, type_::GLenum, indices::Ptr{Void})::Void
@glfunc glCopyTexSubImage3D(target::GLenum, level::GLint, xoffset::GLint, yoffset::GLint, zoffset::GLint, x::GLint, y::GLint, width::GLsizei, height::GLsizei)::Void
@glfunc glStencilMaskSeparate(face::GLenum, mask::GLuint)::Void
@glfunc glGetProgramInfoLog(program::GLuint, bufSize::GLsizei, length::Ptr{GLsizei}, infoLog::Ptr{GLchar})::Void
@glfunc glGetProgramResourceIndex(program::GLuint, programCinterface::GLenum, name::Ptr{GLchar})::GLuint
@glfunc glBlitFramebuffer(srcX0::GLint, srcY0::GLint, srcX1::GLint, srcY1::GLint, dstX0::GLint, dstY0::GLint, dstX1::GLint, dstY1::GLint, mask::GLbitfield, filter::GLenum)::Void
@glfunc glBeginTransformFeedback(primitiveMode::GLenum)::Void
@glfunc glVertexAttribI4bv(index::GLuint, v::Ptr{GLbyte})::Void
@glfunc glIsSampler(sampler::GLuint)::Bool
@glfunc glVertexAttribI4ui(index::GLuint, x::GLuint, y::GLuint, z::GLuint, w::GLuint)::Void
@glfunc glProgramUniformMatrix3x4dv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glCheckFramebufferStatus(target::GLenum)::GLenum
@glfunc glProgramUniformMatrix3fv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glTextureBufferRangeEXT(texture::GLuint, target::GLenum, internalformat::GLenum, buffer::GLuint, offset::GLintptr, size::GLsizeiptr)::Void
@glfunc glInvalidateSubFramebuffer(target::GLenum, numAttachments::GLsizei, attachments::Ptr{GLenum}, x::GLint, y::GLint, width::GLsizei, height::GLsizei)::Void
@glfunc glDeleteTransformFeedbacks(n::GLsizei, ids::Ptr{GLuint})::Void
@glfunc glGetActiveUniformName(program::GLuint, uniformIndex::GLuint, bufSize::GLsizei, length::Ptr{GLsizei}, uniformName::Ptr{GLchar})::Void
@glfunc glPatchParameterfv(pname::GLenum, values::Ptr{GLfloat})::Void
@glfunc glProgramUniform4d(program::GLuint, location::GLint, v0::GLdouble, v1::GLdouble, v2::GLdouble, v3::GLdouble)::Void
@glfunc glSamplerParameteriv(sampler::GLuint, pname::GLenum, param::Ptr{GLint})::Void
@glfunc glTextureStorage2DMultisampleEXT(texture::GLuint, target::GLenum, samples::GLsizei, internalformat::GLenum, width::GLsizei, height::GLsizei, fixedsamplelocations::GLboolean)::Void
@glfunc glStencilOpSeparate(face::GLenum, sfail::GLenum, dpfail::GLenum, dppass::GLenum)::Void
@glfunc glScissorIndexed(index::GLuint, left::GLint, bottom::GLint, width::GLsizei, height::GLsizei)::Void
@glfunc glVertexAttribI3iv(index::GLuint, v::Ptr{GLint})::Void
@glfunc glBeginQueryIndexed(target::GLenum, index::GLuint, id::GLuint)::Void
@glfunc glValidateProgramPipeline(pipeline::GLuint)::Void
@glfunc glUnmapBuffer(target::GLenum)::Bool
@glfunc glEndQuery(target::GLenum)::Void
@glfunc glStencilOp(fail::GLenum, zfail::GLenum, zpass::GLenum)::Void
@glfunc glCompressedTexImage3D(target::GLenum, level::GLint, internalformat::GLenum, width::GLsizei, height::GLsizei, depth::GLsizei, border::GLint, imageSize::GLsizei, data::Ptr{Void})::Void
@glfunc glSampleMaski(index::GLuint, mask::GLbitfield)::Void
@glfunc glDisableVertexAttribArray(index::GLuint)::Void
@glfunc glVertexAttribI2i(index::GLuint, x::GLint, y::GLint)::Void
@glfunc glCompressedTexSubImage2D(target::GLenum, level::GLint, xoffset::GLint, yoffset::GLint, width::GLsizei, height::GLsizei, format::GLenum, imageSize::GLsizei, data::Ptr{Void})::Void
@glfunc glGetVertexAttribPointerv(index::GLuint, pname::GLenum, pointer::Ptr{Ptr{Void}})::Void
@glfunc glDeleteFramebuffers(n::GLsizei, framebuffers::Ptr{GLuint})::Void
@glfunc glUniformMatrix4x2dv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glInvalidateBufferSubData(buffer::GLuint, offset::GLintptr, length::GLsizeiptr)::Void
@glfunc glFramebufferTexture(target::GLenum, attachment::GLenum, texture::GLuint, level::GLint)::Void
@glfunc glTexImage3DMultisample(target::GLenum, samples::GLsizei, internalformat::GLint, width::GLsizei, height::GLsizei, depth::GLsizei, fixedsamplelocations::GLboolean)::Void
@glfunc glVertexAttribL1d(index::GLuint, x::GLdouble)::Void
@glfunc glTextureStorage3DEXT(texture::GLuint, target::GLenum, levels::GLsizei, internalformat::GLenum, width::GLsizei, height::GLsizei, depth::GLsizei)::Void
@glfunc glGetBufferParameteriv(target::GLenum, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glCopyBufferSubData(readTarget::GLenum, writeTarget::GLenum, readOffset::GLintptr, writeOffset::GLintptr, size::GLsizeiptr)::Void
@glfunc glSamplerParameterf(sampler::GLuint, pname::GLenum, param::GLfloat)::Void
@glfunc glColorMask(red::GLboolean, green::GLboolean, blue::GLboolean, alpha::GLboolean)::Void
@glfunc glBlendFuncSeparate(sfactorRGB::GLenum, dfactorRGB::GLenum, sfactorAlpha::GLenum, dfactorAlpha::GLenum)::Void
@glfunc glUniform3fv(location::GLint, count::GLsizei, value::Ptr{GLfloat})::Void
@glfunc glVertexAttribL1dv(index::GLuint, v::Ptr{GLdouble})::Void
@glfunc glUniform4i(location::GLint, v0::GLint, v1::GLint, v2::GLint, v3::GLint)::Void
@glfunc glMultiTexCoordP3ui(texture::GLenum, type_::GLenum, coords::GLuint)::Void
@glfunc glDrawBuffers(n::GLsizei, bufs::Ptr{GLenum})::Void
@glfunc glColorP3ui(type_::GLenum, color::GLuint)::Void
@glfunc glProgramUniformMatrix2x4dv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glVertexP2ui(type_::GLenum, value::GLuint)::Void
@glfunc glDrawElementsInstanced(mode::GLenum, count::GLsizei, type_::GLenum, indices::Ptr{Void}, instancecount::GLsizei)::Void
@glfunc glDrawElementsInstancedEXT(mode::GLenum, count::GLsizei, type_::GLenum, indices::Ptr{Void}, instancecount::GLsizei)::Void
@glfunc glGetUniformiv(program::GLuint, location::GLint, params::Ptr{GLint})::Void
@glfunc glTexImage2D(target::GLenum, level::GLint, internalformat::GLint, width::GLsizei, height::GLsizei, border::GLint, format::GLenum, type_::GLenum, pixels::Ptr{Void})::Void
@glfunc glGetQueryObjecti64v(id::GLuint, pname::GLenum, params::Ptr{GLint64})::Void
@glfunc glGetTexImage(target::GLenum, level::GLint, format::GLenum, type_::GLenum, pixels::Ptr{Void})::Void
@glfunc glGetTexLevelParameteriv(target::GLenum, level::GLint, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glTexSubImage2D(target::GLenum, level::GLint, xoffset::GLint, yoffset::GLint, width::GLsizei, height::GLsizei, format::GLenum, type_::GLenum, pixels::Ptr{Void})::Void
@glfunc glDeleteVertexArrays(n::GLsizei, arrays::Ptr{GLuint})::Void
@glfunc glIsRenderbuffer(renderbuffer::GLuint)::Bool
@glfunc glGetProgramResourceLocationIndex(program::GLuint, programCinterface::GLenum, name::Ptr{GLchar})::GLint
@glfunc glGetInteger64i_v(target::GLenum, index::GLuint, data::Ptr{GLint64})::Void
@glfunc glProgramUniform1ui(program::GLuint, location::GLint, v0::GLuint)::Void
@glfunc glUniform4iv(location::GLint, count::GLsizei, value::Ptr{GLint})::Void
@glfunc glProgramUniform3fv(program::GLuint, location::GLint, count::GLsizei, value::Ptr{GLfloat})::Void
@glfunc glVertexAttribL2d(index::GLuint, x::GLdouble, y::GLdouble)::Void
@glfunc glUniform2d(location::GLint, x::GLdouble, y::GLdouble)::Void
@glfunc glGetBufferParameteri64v(target::GLenum, pname::GLenum, params::Ptr{GLint64})::Void
@glfunc glTexCoordP1ui(type_::GLenum, coords::GLuint)::Void
@glfunc glDeleteBuffers(n::GLsizei, buffers::Ptr{GLuint})::Void
@glfunc glProgramUniformMatrix2x4fv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glMultiTexCoordP4uiv(texture::GLenum, type_::GLenum, coords::Ptr{GLuint})::Void
@glfunc glVertexAttribPointer(index::GLuint, size::GLint, type_::GLenum, normalized::GLboolean, stride::GLsizei, pointer::Ptr{Void})::Void
@glfunc glVertexP3uiv(type_::GLenum, value::Ptr{GLuint})::Void
@glfunc glDispatchComputeIndirect(indirect::GLintptr)::Void
@glfunc glProgramUniform1d(program::GLuint, location::GLint, v0::GLdouble)::Void
@glfunc glGetFloati_v(target::GLenum, index::GLuint, data::Ptr{GLfloat})::Void
@glfunc glDebugMessageControl(source::GLenum, type_::GLenum, severity::GLenum, count::GLsizei, ids::Ptr{GLuint}, enabled::GLboolean)::Void
@glfunc glVertexAttribFormat(attribindex::GLuint, size::GLint, type_::GLenum, normalized::GLboolean, relativeoffset::GLuint)::Void
@glfunc glClearColor(red::GLfloat, green::GLfloat, blue::GLfloat, alpha::GLfloat)::Void
@glfunc glIsFramebuffer(framebuffer::GLuint)::Bool
@glfunc glVertexAttribP1uiv(index::GLuint, type_::GLenum, normalized::GLboolean, value::Ptr{GLuint})::Void
@glfunc glUniform3i(location::GLint, v0::GLint, v1::GLint, v2::GLint)::Void
@glfunc glGetString(name::GLenum)::Ptr{GLchar}
@glfunc glGenTextures(n::GLsizei, textures::Ptr{GLuint})::Void
@glfunc glFramebufferRenderbuffer(target::GLenum, attachment::GLenum, renderbuffertarget::GLenum, renderbuffer::GLuint)::Void
@glfunc glGetQueryObjectiv(id::GLuint, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glBindProgramPipeline(pipeline::GLuint)::Void
@glfunc glGetActiveUniformBlockName(program::GLuint, uniformBlockIndex::GLuint, bufSize::GLsizei, length::Ptr{GLsizei}, uniformBlockName::Ptr{GLchar})::Void
@glfunc glUniformMatrix2fv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glTexStorage3D(target::GLenum, levels::GLsizei, internalformat::GLenum, width::GLsizei, height::GLsizei, depth::GLsizei)::Void
@glfunc glTexCoordP3ui(type_::GLenum, coords::GLuint)::Void
@glfunc glDeleteSync(sync::GLsync)::Void
@glfunc glBindFragDataLocation(program::GLuint, color::GLuint, name::Ptr{GLchar})::Void
@glfunc glGetShaderPrecisionFormat(shadertype::GLenum, precisiontype::GLenum, range_::Ptr{GLint}, precision::Ptr{GLint})::Void
@glfunc glGenTransformFeedbacks(n::GLsizei, ids::Ptr{GLuint})::Void
@glfunc glProgramUniform4iv(program::GLuint, location::GLint, count::GLsizei, value::Ptr{GLint})::Void
@glfunc glHint(target::GLenum, mode::GLenum)::Void
@glfunc glVertexArrayVertexAttribBindingEXT(vaobj::GLuint, attribindex::GLuint, bindingindex::GLuint)::Void
@glfunc glDrawTransformFeedback(mode::GLenum, id::GLuint)::Void
@glfunc glUniform1ui(location::GLint, v0::GLuint)::Void
@glfunc glTexSubImage3D(target::GLenum, level::GLint, xoffset::GLint, yoffset::GLint, zoffset::GLint, width::GLsizei, height::GLsizei, depth::GLsizei, format::GLenum, type_::GLenum, pixels::Ptr{Void})::Void
@glfunc glBeginConditionalRender(id::GLuint, mode::GLenum)::Void
@glfunc glGetActiveUniformsiv(program::GLuint, uniformCount::GLsizei, uniformIndices::Ptr{GLuint}, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glGetStringi(name::GLenum, index::GLuint)::Ptr{GLchar}
@glfunc glMultiDrawArraysIndirect(mode::GLenum, indirect::Ptr{Void}, drawcount::GLsizei, stride::GLsizei)::Void
@glfunc glDepthRange(near_::GLdouble, far_::GLdouble)::Void
@glfunc glUniform2ui(location::GLint, v0::GLuint, v1::GLuint)::Void
@glfunc glBindFragDataLocationIndexed(program::GLuint, colorNumber::GLuint, index::GLuint, name::Ptr{GLchar})::Void
@glfunc glDrawElementsBaseVertex(mode::GLenum, count::GLsizei, type_::GLenum, indices::Ptr{Void}, basevertex::GLint)::Void
@glfunc glMultiTexCoordP4ui(texture::GLenum, type_::GLenum, coords::GLuint)::Void
@glfunc glGetTexParameterfv(target::GLenum, pname::GLenum, params::Ptr{GLfloat})::Void
@glfunc glVertexArrayBindVertexBufferEXT(vaobj::GLuint, bindingindex::GLuint, buffer::GLuint, offset::GLintptr, stride::GLsizei)::Void
@glfunc glScissor(x::GLint, y::GLint, width::GLsizei, height::GLsizei)::Void
@glfunc glClearDepthf(d::GLfloat)::Void
@glfunc glProgramUniformMatrix4x2dv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glDrawElementsInstancedBaseVertex(mode::GLenum, count::GLsizei, type_::GLenum, indices::Ptr{Void}, instancecount::GLsizei, basevertex::GLint)::Void
@glfunc glClearNamedBufferDataEXT(buffer::GLuint, internalformat::GLenum, format::GLenum, type_::GLenum, data::Ptr{Void})::Void
@glfunc glProgramUniform2iv(program::GLuint, location::GLint, count::GLsizei, value::Ptr{GLint})::Void
@glfunc glStencilMask(mask::GLuint)::Void
@glfunc glCopyTexSubImage2D(target::GLenum, level::GLint, xoffset::GLint, yoffset::GLint, x::GLint, y::GLint, width::GLsizei, height::GLsizei)::Void
@glfunc glGetTexLevelParameterfv(target::GLenum, level::GLint, pname::GLenum, params::Ptr{GLfloat})::Void
@glfunc glColorMaski(index::GLuint, r::GLboolean, g::GLboolean, b::GLboolean, a::GLboolean)::Void
@glfunc glVertexP3ui(type_::GLenum, value::GLuint)::Void
@glfunc glUniformMatrix2dv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glGetProgramPipelineInfoLog(pipeline::GLuint, bufSize::GLsizei, length::Ptr{GLsizei}, infoLog::Ptr{GLchar})::Void
@glfunc glVertexAttribP1ui(index::GLuint, type_::GLenum, normalized::GLboolean, value::GLuint)::Void
@glfunc glUniform3iv(location::GLint, count::GLsizei, value::Ptr{GLint})::Void
@glfunc glUniformSubroutinesuiv(shadertype::GLenum, count::GLsizei, indices::Ptr{GLuint})::Void
@glfunc glPatchParameteri(pname::GLenum, value::GLint)::Void
@glfunc glGenVertexArrays(n::GLsizei, arrays::Ptr{GLuint})::Void
@glfunc glStencilFunc(func_::GLenum, ref::GLint, mask::GLuint)::Void
@glfunc glGetInternalformativ(target::GLenum, internalformat::GLenum, pname::GLenum, bufSize::GLsizei, params::Ptr{GLint})::Void
@glfunc glMinSampleShading(value::GLfloat)::Void
@glfunc glProgramUniform2uiv(program::GLuint, location::GLint, count::GLsizei, value::Ptr{GLuint})::Void
@glfunc glGetActiveUniform(program::GLuint, index::GLuint, bufSize::GLsizei, length::Ptr{GLsizei}, size::Ptr{GLint}, type_::Ptr{GLenum}, name::Ptr{GLchar})::Void
@glfunc glVertexAttribI4i(index::GLuint, x::GLint, y::GLint, z::GLint, w::GLint)::Void
@glfunc glClearNamedBufferSubDataEXT(buffer::GLuint, internalformat::GLenum, offset::GLsizeiptr, size::GLsizeiptr, format::GLenum, type_::GLenum, data::Ptr{Void})::Void
@glfunc glUniformMatrix4x2fv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLfloat})::Void
@glfunc glDeleteTextures(n::GLsizei, textures::Ptr{GLuint})::Void
@glfunc glProgramUniformMatrix4dv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glCullFace(mode::GLenum)::Void
@glfunc glProgramUniformMatrix3x2dv(program::GLuint, location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glTexBufferRange(target::GLenum, internalformat::GLenum, buffer::GLuint, offset::GLintptr, size::GLsizeiptr)::Void
@glfunc glClearBufferSubData(target::GLenum, internalformat::GLenum, offset::GLintptr, size::GLsizeiptr, format::GLenum, type_::GLenum, data::Ptr{Void})::Void
@glfunc glLineWidth(width::GLfloat)::Void
@glfunc glCompressedTexSubImage3D(target::GLenum, level::GLint, xoffset::GLint, yoffset::GLint, zoffset::GLint, width::GLsizei, height::GLsizei, depth::GLsizei, format::GLenum, imageSize::GLsizei, data::Ptr{Void})::Void
@glfunc glVertexArrayVertexBindingDivisorEXT(vaobj::GLuint, bindingindex::GLuint, divisor::GLuint)::Void
@glfunc glClearBufferfi(buffer::GLenum, drawbuffer::GLint, depth::GLfloat, stencil::GLint)::Void
@glfunc glIsProgram(program::GLuint)::Bool
@glfunc glGetVertexAttribIiv(index::GLuint, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glGetTransformFeedbackVarying(program::GLuint, index::GLuint, bufSize::GLsizei, length::Ptr{GLsizei}, size::Ptr{GLsizei}, type_::Ptr{GLenum}, name::Ptr{GLchar})::Void
@glfunc glVertexAttribLPointer(index::GLuint, size::GLint, type_::GLenum, stride::GLsizei, pointer::Ptr{Void})::Void
@glfunc glGetFramebufferAttachmentParameteriv(target::GLenum, attachment::GLenum, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glGetActiveAtomicCounterBufferiv(program::GLuint, bufferIndex::GLuint, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glProgramUniform3dv(program::GLuint, location::GLint, count::GLsizei, value::Ptr{GLdouble})::Void
@glfunc glUniformMatrix4x3dv(location::GLint, count::GLsizei, transpose::GLboolean, value::Ptr{GLdouble})::Void
@glfunc glVertexAttribI4ubv(index::GLuint, v::Ptr{GLubyte})::Void
@glfunc glCreateProgram()::GLuint
@glfunc glUniformBlockBinding(program::GLuint, uniformBlockIndex::GLuint, uniformBlockBinding::GLuint)::Void
@glfunc glEndQueryIndexed(target::GLenum, index::GLuint)::Void
@glfunc glTexStorage2DMultisample(target::GLenum, samples::GLsizei, internalformat::GLenum, width::GLsizei, height::GLsizei, fixedsamplelocations::GLboolean)::Void
@glfunc glGetSynciv(sync::GLsync, pname::GLenum, bufSize::GLsizei, length::Ptr{GLsizei}, values::Ptr{GLint})::Void
@glfunc glClampColor(target::GLenum, clamp::GLenum)::Void
@glfunc glVertexAttribP3ui(index::GLuint, type_::GLenum, normalized::GLboolean, value::GLuint)::Void
@glfunc glBindAttribLocation(program::GLuint, index::GLuint, name::Ptr{GLchar})::Void
@glfunc glBindVertexBuffer(bindingindex::GLuint, buffer::GLuint, offset::GLintptr, stride::GLsizei)::Void
@glfunc glValidateProgram(program::GLuint)::Void
@glfunc glGetSamplerParameterfv(sampler::GLuint, pname::GLenum, params::Ptr{GLfloat})::Void
@glfunc glGetBooleani_v(target::GLenum, index::GLuint, data::Ptr{GLboolean})::Void
@glfunc glMultiTexCoordP2uiv(texture::GLenum, type_::GLenum, coords::Ptr{GLuint})::Void
@glfunc glFramebufferTexture2D(target::GLenum, attachment::GLenum, textarget::GLenum, texture::GLuint, level::GLint)::Void
@glfunc glEndTransformFeedback()::Void
@glfunc glGetSubroutineUniformLocation(program::GLuint, shadertype::GLenum, name::Ptr{GLchar})::GLint
@glfunc glGetQueryiv(target::GLenum, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glProgramUniform2d(program::GLuint, location::GLint, v0::GLdouble, v1::GLdouble)::Void
@glfunc glProgramUniform3iv(program::GLuint, location::GLint, count::GLsizei, value::Ptr{GLint})::Void
@glfunc glIsSync(sync::GLsync)::Bool
@glfunc glGetTexParameterIiv(target::GLenum, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glGetObjectPtrLabel(ptr::Ptr{Void}, bufSize::GLsizei, length::Ptr{GLsizei}, label::Ptr{GLchar})::Void
@glfunc glGetUniformSubroutineuiv(shadertype::GLenum, location::GLint, params::Ptr{GLuint})::Void
@glfunc glTexBuffer(target::GLenum, internalformat::GLenum, buffer::GLuint)::Void
@glfunc glDeleteQueries(n::GLsizei, ids::Ptr{GLuint})::Void
@glfunc glDisablei(target::GLenum, index::GLuint)::Void
@glfunc glNamedFramebufferParameteriEXT(framebuffer::GLuint, pname::GLenum, param::GLint)::Void
@glfunc glGetUniformLocation(program::GLuint, name::Ptr{GLchar})::GLint
@glfunc glMemoryBarrier(barriers::GLbitfield)::Void
@glfunc glGetDoublei_v(target::GLenum, index::GLuint, data::Ptr{GLdouble})::Void
@glfunc glClearBufferuiv(buffer::GLenum, drawbuffer::GLint, value::Ptr{GLuint})::Void
@glfunc glRenderbufferStorage(target::GLenum, internalformat::GLenum, width::GLsizei, height::GLsizei)::Void
@glfunc glViewportIndexedf(index::GLuint, x::GLfloat, y::GLfloat, w::GLfloat, h::GLfloat)::Void
@glfunc glDrawElements(mode::GLenum, count::GLsizei, type_::GLenum, indices::Ptr{Void})::Void
@glfunc glVertexAttribI1ui(index::GLuint, x::GLuint)::Void
@glfunc glUniform2i(location::GLint, v0::GLint, v1::GLint)::Void
@glfunc glGetQueryIndexediv(target::GLenum, index::GLuint, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glAttachShader(program::GLuint, shader::GLuint)::Void
@glfunc glDrawTransformFeedbackStreamInstanced(mode::GLenum, id::GLuint, stream::GLuint, instancecount::GLsizei)::Void
@glfunc glIsQuery(id::GLuint)::Bool
@glfunc glViewportIndexedfv(index::GLuint, v::Ptr{GLfloat})::Void
@glfunc glVertexBindingDivisor(bindingindex::GLuint, divisor::GLuint)::Void
@glfunc glCopyTexImage2D(target::GLenum, level::GLint, internalformat::GLenum, x::GLint, y::GLint, width::GLsizei, height::GLsizei, border::GLint)::Void
@glfunc glDeleteSamplers(count::GLsizei, samplers::Ptr{GLuint})::Void
@glfunc glGetProgramStageiv(program::GLuint, shadertype::GLenum, pname::GLenum, values::Ptr{GLint})::Void
@glfunc glBindSampler(unit::GLuint, sampler::GLuint)::Void
@glfunc glBindRenderbuffer(target::GLenum, renderbuffer::GLuint)::Void
@glfunc glGetSamplerParameterIuiv(sampler::GLuint, pname::GLenum, params::Ptr{GLuint})::Void
@glfunc glGetTexParameteriv(target::GLenum, pname::GLenum, params::Ptr{GLint})::Void
@glfunc glVertexAttribIFormat(attribindex::GLuint, size::GLint, type_::GLenum, relativeoffset::GLuint)::Void
@glfunc glBlendEquationSeparatei(buf::GLuint, modeRGB::GLenum, modeAlpha::GLenum)::Void
@glfunc glTexImage2DMultisample(target::GLenum, samples::GLsizei, internalformat::GLint, width::GLsizei, height::GLsizei, fixedsamplelocations::GLboolean)::Void
@glfunc glDepthRangef(n::GLfloat, f::GLfloat)::Void
@glfunc glUniform4f(location::GLint, v0::GLfloat, v1::GLfloat, v2::GLfloat, v3::GLfloat)::Void
@glfunc glMapBuffer(target::GLenum, access::GLenum)::Ptr{Void}


text:
# EXCLUDE FROM TESTING
# this example might fail (CUDA error, or runtime trap if bounds-checking if enabled)

# Running this example under cuda-memset properly gives line number info,
# demonstrating how we support existing CUDA tools.

# TODO: make the actual error trap at run time

using CUDAdrv, CUDAnative, CuArrays

a = CuArray{Float32}(undef, 10)

function memset(a, val)
    i = (blockIdx().x-1) * blockDim().x + threadIdx().x
    a[i] = val
    return
end

@cuda threads=11 memset(a, 0f0)
synchronize()

ext: jl


text:
using Pkg

Pkg.activate(homedir() * "/Documents/Coding/gpublockbanded")
using BandedMatrices, BlockBandedMatrices, SharedArrays, ArrayLayouts, BlockArrays, FillArrays
import BlockBandedMatrices: _BandedBlockBandedMatrix, BandedBlockBandedSizes, BlockSizes, blockcolsupport
import BandedMatrices: AbstractBandedMatrix, bandwidths, BandedStyle
import Base: getindex, size

struct FiniteDifference{T} <: AbstractBandedMatrix{T}
    n::Int
end

FiniteDifference(n) = FiniteDifference{Float64}(n)

getindex(F::FiniteDifference{T}, k::Int, j::Int) where T =
    if k == j
        -2*one(T)*F.n^2
    elseif abs(k-j) == 1
        one(T)*F.n^2
    else
        zero(T)
    end

bandwidths(F::FiniteDifference) = (1,1)
size(F::FiniteDifference) = (F.n,F.n)

Base.BroadcastStyle(::Type{<:Eye}) = BandedStyle()

function blockcolbuild!(ret, A, JR)
    for J in JR, K in blockcolsupport(A,J)
        view(ret,K,J) .= view(A,K,J)
    end
end


text:
using Test
using DFTK: energy_ewald
using LinearAlgebra

@testset "Hydrogen atom" begin
    lattice = 16 * Diagonal(ones(3))
    charges = [1]
    positions = [[0,0,0]]

    ref = -0.088665545  # TODO source?
    γ_E = energy_ewald(lattice, charges, positions)
    @test abs(γ_E - ref) < 1e-8
end

@testset "Silicon diamond structure" begin
    lattice = [0.0  5.131570667152971 5.131570667152971;
               5.131570667152971 0.0 5.131570667152971;
               5.131570667152971 5.131570667152971  0.0]
    positions = [ones(3)/8, -ones(3)/8]
    charges = [14, 14]

    ref = -102.8741963352893
    γ_E = energy_ewald(lattice, charges, positions)
    @test abs(γ_E - ref) < 1e-8
end

@testset "Boron molecule" begin
    lattice = 16 * Diagonal(ones(3))
    positions = [[0,0,0], [0.14763485355139283, 0, 0]]
    charges = [5, 5]

    ref = 1.790634595  # TODO source?
    γ_E = energy_ewald(lattice, charges, positions)
    @test abs(γ_E - ref) < 1e-7
end

@testset "Hydrogen molecule" begin
    lattice = 16 * Diagonal(ones(3))
    positions = [
        [0.45312500031210007, 1/2, 1/2],
        [0.5468749996028622, 1/2, 1/2],
    ]
    charges = [1, 1]

    ref = 0.31316999  # TODO source?
    γ_E = energy_ewald(lattice, charges, positions)
    @test abs(γ_E - ref) < 1e-7
end

@testset "Forces" begin
    lattice = [0.0  5.131570667152971 5.131570667152971;
               5.131570667152971 0.0 5.131570667152971;
               5.131570667152971 5.131570667152971  0.0]
    # perturb positions away from equilibrium to get nonzero force
    positions = [ones(3)/8+rand(3)/20, -ones(3)/8]
    charges = [14, 14]

    forces = zeros(Vec3{Float64}, 2)
    γ1 = energy_ewald(lattice, charges, positions, forces=forces)

    # Compare forces to finite differences
    disp = [rand(3)/20, rand(3)/20]
    ε = 1e-8
    γ2 = energy_ewald(lattice, charges, positions .+ ε .* disp)
    @test (γ2-γ1)/ε ≈ -dot(disp, forces) atol=abs(γ1*1e-6)
end


text:
using DynamicGrids, Test
import DynamicGrids: applyrule, applyrule!, maprule!,
       SimData, source, dest, currenttime

init  = [0 1 1 0;
         0 1 1 0;
         0 1 1 0;
         0 1 1 0;
         0 1 1 0]

struct TestRule <: Rule end
applyrule(::TestRule, data, state, index) = 0

@testset "a rule that returns zero gives zero outputs" begin
    final = [0 0 0 0;
             0 0 0 0;
             0 0 0 0;
             0 0 0 0;
             0 0 0 0]

    ruleset = Ruleset(TestRule(); init=init)
    data = SimData(ruleset, init, 1)
    maprule!(data, ruleset.rules[1])
    @test dest(data) == final
end

struct TestPartial <: PartialRule end
applyrule!(::TestPartial, data, state, index) = 0

@testset "a partial rule that returns zero does nothing" begin
    ruleset = Ruleset(TestPartial(); init=init)
    data = SimData(ruleset, init, 1)
    maprule!(data, ruleset.rules[1])
    @test dest(data) == init
end

struct TestPartialWrite <: PartialRule end
applyrule!(::TestPartialWrite, data, state, index) = data[index[1], 2] = 0

@testset "a partial rule that writes to dest affects output" begin
    final = [0 0 1 0;
             0 0 1 0;
             0 0 1 0;
             0 0 1 0;
             0 0 1 0]

    ruleset = Ruleset(TestPartialWrite(); init=init)
    data = SimData(ruleset, init, 1)
    maprule!(data, ruleset.rules[1])
    @test dest(data) == final
end

struct TestCellTriple <: CellRule end
applyrule(::TestCellTriple, data, state, index) = 3state

struct TestCellSquare <: CellRule end
applyrule(::TestCellSquare, data, state, index) = state^2

@testset "a chained cell rull" begin
    init  = [0 1 2 3;
             4 5 6 7]

    final = [0 9 36 81;
             144 225 324 441]

    ruleset = Ruleset(Chain(TestCellTriple(), TestCellSquare()); init=init)
    data = SimData(ruleset, init, 1)
    maprule!(data, ruleset.rules[1])
    @test dest(data) == final
end

struct PrecalcRule{P} <: Rule
    precalc::P
end
DynamicGrids.precalcrules(rule::PrecalcRule, data) =
    PrecalcRule(currenttime(data))
applyrule(rule::PrecalcRule, data, state, index) = rule.precalc[]

@testset "a rule with precalculations" begin
    init  = [1 1;
             1 1]

    out2  = [2 2;
             2 2]

    out3  = [3 3;
             3 3]

    ruleset = Ruleset(PrecalcRule(1); init=init)
    output = ArrayOutput(init, 3)
    sim!(output, ruleset; tspan=(1, 3))
    @test output[2] == out2
    @test output[3] == out3
end


text:
using LinearAlgebra
using SparseArrays

"""
    space(::SiteType"HubHolst";
          conserve_qns = false,
          conserve_sz = conserve_qns,
          conserve_nf = conserve_qns,
          conserve_nfparity = conserve_qns,
          qnname_sz = "Sz",
          qnname_nf = "Nf",
          qnname_nfparity = "NfParity")

Create the Hilbert space for a site of type "HubHolst".

Optionally specify the conserved symmetries and their quantum number labels.
"""
function ITensors.space(
  ::SiteType"HubHolst";
  dim=2, #Default is 1 phonon
  conserve_qns=true,
  conserve_sz=conserve_qns,
  conserve_nf=conserve_qns,
  conserve_nfparity=conserve_qns,
  qnname_sz="Sz",
  qnname_nf="Nf",
  qnname_nfparity="NfParity")

  # if dim > 2 ### NOTE: need to determine the optimal tradeoff between QN conservation and LBO
  #   return 4 * dim
  # end

  if conserve_sz && conserve_nf
    return [
      QN((qnname_nf, 0, -1), (qnname_sz, 0)) => 1 * dim
      QN((qnname_nf, 1, -1), (qnname_sz, +1)) => 1 * dim
      QN((qnname_nf, 1, -1), (qnname_sz, -1)) => 1 * dim
      QN((qnname_nf, 2, -1), (qnname_sz, 0)) => 1 * dim
    ]
  elseif conserve_nf
    return [
      QN(qnname_nf, 0, -1) => 1 * dim
      QN(qnname_nf, 1, -1) => 2 * dim
      QN(qnname_nf, 2, -1) => 1 * dim
    ]
  elseif conserve_sz
    return [
      QN((qnname_sz, 0), (qnname_nfparity, 0, -2)) => 1 * dim
      QN((qnname_sz, +1), (qnname_nfparity, 1, -2)) => 1 * dim
      QN((qnname_sz, -1), (qnname_nfparity, 1, -2)) => 1 * dim
      QN((qnname_sz, 0), (qnname_nfparity, 0, -2)) => 1 * dim
    ]
  elseif conserve_nfparity
    return [
      QN(qnname_nfparity, 0, -2) => 1 * dim
      QN(qnname_nfparity, 1, -2) => 2 * dim
      QN(qnname_nfparity, 0, -2) => 1 * dim
    ]
  end
  return 4 * dim
end

function ITensors.val(::ValName{N}, ::SiteType"HubHolst") where {N}
    hubbard_type, phonon_num = split(String(N), ",")
    if hubbard_type == "Emp"
        n1 = 1
    elseif hubbard_type == "Up"
        n1 = 2
    elseif hubbard_type == "Dn"
        n1 = 3
    elseif hubbard_type == "UpDn"
        n1 = 4
    else
        throw(DomainError(hubbard_type, "expects Emp, Up, Dn, UpDn"))
    end

    n2 = parse(Int, String(phonon_num)) + 1
    return n1+n2
end

function ITensors.state(n::StateName{N}, ::SiteType"HubHolst", s::Index) where {N}
    hubbard_type, n = split(String(name(n)), ",")
    n = parse(Int, n)

    if hubbard_type == "Emp"
        st_hubb = [1, 0, 0, 0]
    elseif hubbard_type == "Up"
        st_hubb = [0, 1, 0, 0]
    elseif hubbard_type == "Dn"
        st_hubb = [0, 0, 1, 0]
    elseif hubbard_type == "UpDn"
        st_hubb = [0, 0, 0, 1]
    else
        throw(DomainError(hubbard_type, "expects Emp, Up, Dn, UpDn"))
    end

    st_ph = zeros(floor(Int,dim(s)/4))
    st_ph[n+1] = 1

    return kron(st_hubb, st_ph)
end

## ELECTRON OPERATORS ##

function ITensors.op(::OpName"I", ::SiteType"HubHolst", s::Index)
  M = Matrix(I, Int(dim(s)), Int(dim(s)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Nup", ::SiteType"HubHolst", s::Index)
  Nup = [
    0.0 0.0 0.0 0.0
    0.0 1.0 0.0 0.0
    0.0 0.0 0.0 0.0
    0.0 0.0 0.0 1.0
  ]
  M = kron(Nup, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Ndn", ::SiteType"HubHolst", s::Index)
  Ndn = [
      0.0 0.0 0.0 0.0
      0.0 0.0 0.0 0.0
      0.0 0.0 1.0 0.0
      0.0 0.0 0.0 1.0
    ]
  M = kron(Ndn, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Nupdn", ::SiteType"HubHolst", s::Index)
  Nupdn = [
    0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0
    0.0 0.0 0.0 1.0
  ]
  M = kron(Nupdn, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Ntot", ::SiteType"HubHolst", s::Index)
  Ntot = [
    0.0 0.0 0.0 0.0
    0.0 1.0 0.0 0.0
    0.0 0.0 1.0 0.0
    0.0 0.0 0.0 2.0
  ]
  M = kron(Ntot, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Cup", ::SiteType"HubHolst", s::Index)
  Cup = [
    0.0 1.0 0.0 0.0
    0.0 0.0 0.0 0.0
    0.0 0.0 0.0 1.0
    0.0 0.0 0.0 0.0
  ]
  M = kron(Cup, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Cdagup", ::SiteType"HubHolst", s::Index)
  Cdagup = [
    0.0 0.0 0.0 0.0
    1.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0
    0.0 0.0 1.0 0.0
  ]
  M = kron(Cdagup, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Cdn", ::SiteType"HubHolst", s::Index)
  Cdn = [
    0.0 0.0 1.0 0.0
    0.0 0.0 0.0 -1.0
    0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0
  ]
  M = kron(Cdn, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Cupdn", ::SiteType"HubHolst", s::Index)
  Cupdn = [
    0.0  0.0  0.0  -1.0
    0.0  0.0  0.0   0.0
    0.0  0.0  0.0   0.0
    0.0  0.0  0.0   0.0
  ]
  M = kron(Cupdn, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Cdagupdn", ::SiteType"HubHolst", s::Index)
  Cdagupdn = [
    0.0  0.0  0.0   0.0
    0.0  0.0  0.0   0.0
    0.0  0.0  0.0   0.0
   -1.0  0.0  0.0   0.0
  ]
  M = kron(Cdagupdn, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Cdagdn", ::SiteType"HubHolst", s::Index)
  Cdagdn = [
    0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0
    1.0 0.0 0.0 0.0
    0.0 -1.0 0.0 0.0
  ]
  M = kron(Cdagdn, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Aup", ::SiteType"HubHolst", s::Index)
  Aup = [
    0.0 1.0 0.0 0.0
    0.0 0.0 0.0 0.0
    0.0 0.0 0.0 1.0
    0.0 0.0 0.0 0.0
  ]
  M = kron(Aup, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Adagup", ::SiteType"HubHolst", s::Index)
  Adagup = [
    0.0 0.0 0.0 0.0
    1.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0
    0.0 0.0 1.0 0.0
  ]
  M = kron(Adagup, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Adn", ::SiteType"HubHolst", s::Index)
  Adn = [
    0.0 0.0 1.0 0.0
    0.0 0.0 0.0 -1.0
    0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0
  ]
  M = kron(Adn, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Adagdn", ::SiteType"HubHolst", s::Index)
  Adagdn = [
    0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0
    1.0 0.0 0.0 0.0
    0.0 -1.0 0.0 0.0
  ]
  M = kron(Adagdn, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"F", ::SiteType"HubHolst", s::Index)
  F = [
    1.0 0.0 0.0 0.0
    0.0 -1.0 0.0 0.0
    0.0 0.0 -1.0 0.0
    0.0 0.0 0.0 1.0
  ]
  M = kron(F, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Fup", ::SiteType"HubHolst", s::Index)
  Fup = [
    1.0 0.0 0.0 0.0
    0.0 -1.0 0.0 0.0
    0.0 0.0 1.0 0.0
    0.0 0.0 0.0 -1.0
  ]
  M = kron(Fup, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Fdn", ::SiteType"HubHolst", s::Index)
  Fdn = [
    1.0 0.0 0.0 0.0
    0.0 1.0 0.0 0.0
    0.0 0.0 -1.0 0.0
    0.0 0.0 0.0 -1.0
  ]
  M = kron(Fdn, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"fSWAP", ::SiteType"HubHolst", s1::Index, s2::Index)
  fSWAP = [
    1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0
    0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0 0.0 -1. 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0
    0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -1. 0.0 0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0
    0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0
  ]
  phonon_dim = floor(Int,dim(s1)/4)
  M = kron(fSWAP, Matrix(I, phonon_dim^2, phonon_dim^2))
  ITensor(M, prime(s1), dag(s1), prime(s2), dag(s2))
end

function ITensors.op(::OpName"Sz", ::SiteType"HubHolst", s::Index)
  Sz = [
    0.0 0.0 0.0 0.0
    0.0 0.5 0.0 0.0
    0.0 0.0 -0.5 0.0
    0.0 0.0 0.0 0.0
  ]
  M = kron(Sz, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Sx", ::SiteType"HubHolst", s::Index)
  Sx = [
    0.0 0.0 0.0 0.0
    0.0 0.0 0.5 0.0
    0.0 0.5 0.0 0.0
    0.0 0.0 0.0 0.0
  ]
  M = kron(Sx, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"S+", ::SiteType"HubHolst", s::Index)
  Splus = [
    0.0 0.0 0.0 0.0
    0.0 0.0 1.0 0.0
    0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0
  ]
  M = kron(Splus, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"S-", ::SiteType"HubHolst", s::Index)
  Sminus = [
    0.0 0.0 0.0 0.0
    0.0 0.0 0.0 0.0
    0.0 1.0 0.0 0.0
    0.0 0.0 0.0 0.0
  ]
  M = kron(Sminus, Matrix(I, floor(Int,dim(s)/4), floor(Int,dim(s)/4)))
  ITensor(M, prime(s), dag(s))
end

ITensors.has_fermion_string(::OpName"Cup", ::SiteType"HubHolst") = true
function ITensors.has_fermion_string(on::OpName"c↑", st::SiteType"HubHolst")
  return has_fermion_string(alias(on), st)
end
ITensors.has_fermion_string(::OpName"Cdagup", ::SiteType"HubHolst") = true
function ITensors.has_fermion_string(on::OpName"c†↑", st::SiteType"HubHolst")
  return has_fermion_string(alias(on), st)
end
ITensors.has_fermion_string(::OpName"Cdn", ::SiteType"HubHolst") = true
function ITensors.has_fermion_string(on::OpName"c↓", st::SiteType"HubHolst")
  return has_fermion_string(alias(on), st)
end
ITensors.has_fermion_string(::OpName"Cdagdn", ::SiteType"HubHolst") = true
function ITensors.has_fermion_string(on::OpName"c†↓", st::SiteType"HubHolst")
  return has_fermion_string(alias(on), st)
end

## PHONON OPERATORS ##

function ITensors.op(::OpName"B", ::SiteType"HubHolst", s::Index)
  @assert floor(Int,dim(s)/4) > 1 "Must allow a nonzero number of phonons"

  B = Tridiagonal(zeros(floor(Int,dim(s)/4)-1),zeros(floor(Int,dim(s)/4)),sqrt.(collect(1:floor(Int,dim(s)/4)-1)))
  M = kron(Matrix(I, 4, 4), B)
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Bdag", ::SiteType"HubHolst", s::Index)
  @assert floor(Int,dim(s)/4) > 1 "Must allow a nonzero number of phonons"

  Bdag = sparse(Tridiagonal(sqrt.(collect(1:floor(Int,dim(s)/4)-1)),zeros(floor(Int,dim(s)/4)),zeros(floor(Int,dim(s)/4)-1)))
  M = kron(Matrix(I, 4, 4), Bdag)
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Nb", ::SiteType"HubHolst", s::Index)
  @assert floor(Int,dim(s)/4) > 1 "Must allow a nonzero number of phonons"

  Bdag = sparse(Tridiagonal(sqrt.(collect(1:floor(Int,dim(s)/4)-1)),zeros(floor(Int,dim(s)/4)),zeros(floor(Int,dim(s)/4)-1)))
  B = Tridiagonal(zeros(floor(Int,dim(s)/4)-1),zeros(floor(Int,dim(s)/4)),sqrt.(collect(1:floor(Int,dim(s)/4)-1)))
  M = kron(Matrix(I, 4, 4), (Bdag * B))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Nb^2", ::SiteType"HubHolst", s::Index)
  @assert floor(Int,dim(s)/4) > 1 "Must allow a nonzero number of phonons"

  Bdag = sparse(Tridiagonal(sqrt.(collect(1:floor(Int,dim(s)/4)-1)),zeros(floor(Int,dim(s)/4)),zeros(floor(Int,dim(s)/4)-1)))
  B = Tridiagonal(zeros(floor(Int,dim(s)/4)-1),zeros(floor(Int,dim(s)/4)),sqrt.(collect(1:floor(Int,dim(s)/4)-1)))
  M = kron(Matrix(I, 4, 4), (Bdag * B * Bdag * B))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Bdag+B", ::SiteType"HubHolst", s::Index)
  @assert floor(Int,dim(s)/4) > 1 "Must allow a nonzero number of phonons"

  Bdag = sparse(Tridiagonal(sqrt.(collect(1:floor(Int,dim(s)/4)-1)),zeros(floor(Int,dim(s)/4)),zeros(floor(Int,dim(s)/4)-1)))
  B = Tridiagonal(zeros(floor(Int,dim(s)/4)-1),zeros(floor(Int,dim(s)/4)),sqrt.(collect(1:floor(Int,dim(s)/4)-1)))
  M = kron(Matrix(I, 4, 4), (Bdag + B))
  ITensor(M, prime(s), dag(s))
end

function ITensors.op(::OpName"Ntot(Bd+B)", ::SiteType"HubHolst", s::Index)
  # Fermion part
  Ntot = [
    0.0 0.0 0.0 0.0
    0.0 1.0 0.0 0.0
    0.0 0.0 1.0 0.0
    0.0 0.0 0.0 2.0
  ]

  # Make B†+B
  @assert floor(Int,dim(s)/4) > 1 "Must allow a nonzero number of phonons"

  Bdag = sparse(Tridiagonal(sqrt.(collect(1:floor(Int,dim(s)/4)-1)),zeros(floor(Int,dim(s)/4)),zeros(floor(Int,dim(s)/4)-1)))
  B = Tridiagonal(zeros(floor(Int,dim(s)/4)-1),zeros(floor(Int,dim(s)/4)),sqrt.(collect(1:floor(Int,dim(s)/4)-1)))
  M = kron(Ntot, (Bdag + B))
  ITensor(M, prime(s), dag(s))
end


text:
# Transcoding State
# =================

# See docs/src/devnotes.md.
"""
A mutable state type of transcoding streams.

See Developer's notes for details.
"""
mutable struct State
    # current stream mode
    mode::Symbol  # {:idle, :read, :write, :stop, :close, :panic}

    # return code of the last method call
    code::Symbol  # {:ok, :end, :error}

    # flag to go :stop on :end
    stop_on_end::Bool

    # exception thrown while data processing
    error::Error

    # data buffers
    buffer1::Buffer
    buffer2::Buffer

    function State(buffer1::Buffer, buffer2::Buffer)
        return new(:idle, :ok, false, Error(), buffer1, buffer2)
    end
end

function State(size::Integer)
    return State(Buffer(size), Buffer(size))
end


text:
abstract type RandomizeProblem end

immutable RandomizeInitialx{T<:AbstractArray} <: RandomizeProblem
    seeds::T
end

immutable RandomizeInitialxMat{T<:AbstractArray} <: RandomizeProblem
    seeds::T
end

Base.length(r::RandomizeProblem) = length(r.seeds)

function randomizeproblem!(prob::OptimizationProblem, rnd::RandomizeInitialx, k::Int)
    srand(rnd.seeds[k])
    rand!(prob.initial_x)
end

function randomizeproblem!(prob::OptimizationProblem, rnd::RandomizeInitialxMat, k::Int)
    srand(rnd.seeds[k])
    rand!(prob.initial_x)
    prob.parameters.mat .= UP._randommatrix(length(prob.initial_x), true)
end


text:
include("dynamic_symtridiagonal.jl")
using LinearAlgebra, Plots

function CharPolyEvolution(n=10)
    mainDiag = rand(n)
    subDiag = rand(n - 1)
    dynamicT = DynamicSymTridiagonal(mainDiag[1])
    Grid = LinRange(-1, 1, 101) |> collect
    fig = plot(legend=false)
    for Idx in 1:n - 1
        dynamicT(mainDiag[Idx + 1], subDiag[Idx])
        p = Grid .|>(x) -> CharPolyShifted(dynamicT, x)
        plot!(fig, Grid, sign.(p).*log10.(abs.(p) .+ 1))
    end
    display(fig)
return end

# CharPolyEvolution()

function MakeMeRandDynamicTridiagonal(n=10)
    mainDiag = rand(n)
    subDiag = rand(n - 1)
    dynamicT = DynamicSymTridiagonal(mainDiag[1])
    for Idx in 1:n - 1
        dynamicT(mainDiag[Idx + 1], subDiag[Idx])
    end
return dynamicT end

# DymT = MakeMeRandDynamicTridiagonal()

function ViewConvergence(n=2048)
    a = 1; b = 1/2
    mainDiag = -a*ones(n)
    subDiag = b*ones(n)
    mainDiag .+= a + 2b
    referenceT = SymTridiagonal(mainDiag, subDiag)
    # referenceT = referenceT*3
    mainDiag = referenceT.dv
    subDiag = referenceT.ev
    dynamicT = DynamicSymTridiagonal(mainDiag[1])
    dynamicT.velocity_tol = 1e-4
    fig1=plot(legend=nothing)
    for Idx in n÷16:-1:2
        dynamicT(mainDiag[Idx + 1], subDiag[Idx])
        EigenvaluesUpdate(dynamicT)
        dynamicEigs = dynamicT.thetas |> sort
        scatter!(
            fig1,
            dynamicEigs,
            Idx*ones(dynamicEigs |> length),
            markershape=:cross
        )
        convergedRitz = GetConverged(dynamicT)
        scatter!(
            fig1,
            convergedRitz,
            Idx*(convergedRitz |> length |> ones),
            markershape=:square
        )
        if dynamicT.converged_this_step |> length >= 1
            println("Ritzvalues: $(dynamicT.converged_this_step); converged at step $Idx")
        end
    end

    referenceEigs = eigvals(referenceT) |> sort
    scatter!(
        fig1,
        referenceEigs,
        zeros(referenceEigs |> length),
        markershape=:x
    )

    display(fig1)
end

ViewConvergence()


text:
MatchCore = :(
module MatchCore
    using MLStyle
    using MLStyle.Toolz.List
    using MLStyle.Err
    using MLStyle.Render

    export Failed, failed
    struct Failed end
    const failed = Failed()

    export Qualifier
    Qualifier = Function

    export internal, invasive, share_with, share_through

    internal = (my_mod, umod) -> my_mod === umod
    invasive = (my_mod, umod) -> true
    share_with(ms::Set{Module}) = (_, umod) -> umod in ms

    export qualifier_test
    function qualifier_test(qualifiers :: Set{Qualifier}, use_mod, def_mod)
        any(qualifiers) do q
            q(def_mod, use_mod)
        end
    end

    export PDesc
    struct PDesc
        # for gapp patterns: (spec_vars :: Vector{Any}, gapobject :: Object, tl :: Vector{AST}) -> bool
        # for app patterns: (appobject :: Object, tl :: Vector{AST}) -> bool
        # for general    : (case:AST) -> bool

        predicate  :: Function

        # for gapp:
        #    (to_match : Symbol,
        #     forall :: Vector{Any},
        #     spec_vars :: Vector{Any},
        #     appobject :: Object,
        #     args :: Vector{AST},
        #     mod :: Module) -> (AST -> AST)
        # for app: (to_match  : Symbol, appobject: Object, args::Vector{AST}, mod::Module) -> (AST -> AST)
        # general: (to_match  : Symbol, case:AST, mod :: Module) -> (AST -> AST)
        rewrite    :: Function

        qualifiers :: Set{Qualifier}
    end

    PDesc(;predicate, rewrite, qualifiers) =
        PDesc(predicate, rewrite, qualifiers)

    # A bug occurred when key is of Module type.
    # Tentatively we use associate list(vector?).

    const PATTERNS = Vector{Tuple{Module, PDesc}}()

    export register_pattern

    function register_pattern(pdesc :: PDesc, defmod :: Module)
        push!(PATTERNS, (defmod, pdesc))
    end
    function get_pattern(case, use_mod :: Module)
        for (def_mod, desc) in PATTERNS
            if qualifier_test(desc.qualifiers, use_mod, def_mod) && desc.predicate(case)
                return desc.rewrite
            end
        end
    end

    const INTERNAL_COUNTER = Dict{Module, Int}()

    function remove_module_patterns(mod :: Module)
        delete!(INTERNAL_COUNTER, mod)
    end

    function get_name_of_module(m::Module) :: String
        string(m)
    end

    export mangle
    function mangle(mod::Module)
        get!(INTERNAL_COUNTER, mod) do
            0
        end |> id -> begin
            INTERNAL_COUNTER[mod] = id + 1
            mod_name = get_name_of_module(mod)
            gensym("$mod_name $id")
        end

    end

    export gen_match, @match
    macro match(target, cbl)
       gen_match(target, cbl, __source__, __module__) |> esc
    end

    function gen_match(target, cbl, init_loc :: LineNumberNode, mod :: Module)
        branches = @matchast cbl quote
            begin
                $((branches && Many(:($a => $b) || ::LineNumberNode))...)
            end => branches
            $_ => throw(SyntaxError("Malformed syntax, expect `begin a => b; ... end` as match's branches., at " * string(init_loc)))
        end
        loc = init_loc
        branches_located = map(branches) do each
            @match each begin
                :($pattern => $body) =>
                    (pattern, body, loc)
                curloc::LineNumberNode =>
                    begin
                        loc = curloc
                        nothing
                    end
                _ => throw(SyntaxError("Malformed ast template, should be formed as `a => b`, at "* string(last_lnode) * "."))
            end
        end |> xs -> filter(x -> x !== nothing, xs)
        final = let loc_str = string(init_loc),
                    exc_throw = Expr(:call, InternalException, "Non-exhaustive pattern found, at " * loc_str * "!")
                    @format [init_loc, throw, exc_throw] quote
                        init_loc
                        throw(exc_throw)
                    end
                end
        result = mangle(mod)  # return of pattern matching
        tag_sym = mangle(mod) # value to match

        foldr(branches_located, init=final) do (pattern, body, loc), last
            expr = mk_pattern(tag_sym, pattern, mod)(body)
            @format [
                result,
                expr,
                loc,
                MatchCore,
                last
            ] quote
                loc
                result = expr
                result === $MatchCore.failed ? last : result
            end
        end |> main_logic ->
        @format [tag_sym, target, main_logic] quote
            let tag_sym = target
                main_logic
            end
        end
    end

    export mk_pattern
    function mk_pattern(tag_sym :: Symbol, case :: Any, mod :: Module)
        rewrite = get_pattern(case, mod)
        if rewrite !== nothing
            return rewrite(tag_sym, case, mod)
        end
        case = string(case)
        throw(PatternUnsolvedException("invalid usage or unknown case $case"))
     end
end)


text:
@testset "Test SparseMatrixCOO" begin
    i = Int[1, 4, 2, 1]
    j = Int[1, 4, 2, 3]
    v = Float64[4, 5, 7, 8]
    coo = ms.SparseMatrixCOO(4, 4, i, j, v)
    coo_py = ms.to_python(coo)

    @test ms.to_sparse_csc(coo) == Float64[4 0 8 0;
                                           0 7 0 0;
                                           0 0 0 0;
                                           0 0 0 5]
    @test ms.to_full(coo) == Float64[4 0 8 0;
                                     0 7 0 0;
                                     0 0 0 0;
                                     0 0 0 5]
    @test coo_py["dot"]([1, 2, 3, 4]) == Float64[28, 14, 0, 20]
    @test coo_py["toarray"]() == Float64[4 0 8 0;
                                         0 7 0 0;
                                         0 0 0 0;
                                         0 0 0 5]
end

@testset "Test LinearOperator" begin
    i = Int[1, 4, 2, 1]
    j = Int[1, 4, 2, 3]
    v = Float64[4, 5, 7, 8]
    A = sparse(i, j, v, 4, 4)
    matvec(x) = A*x
    A_op = ms.LinearOperator(4, 4, matvec)
    A_py = ms.to_python(A_op)

    @test dot(A_op, [1, 2, 3, 4]) == Float64[28, 14, 0, 20]
    @test A_py["dot"]([1, 2, 3, 4]) == Float64[28, 14, 0, 20]
end


text:
module Compiler

using InteractiveUtils

import ..Highlights: AbstractLexer
import ..Highlights.Tokens: Tokens, TokenValue, ERROR

mutable struct Mut{T}
    value::T
end

Base.getindex(m::Mut) = m.value
Base.setindex!(m::Mut, v) = m.value = v

struct Token
    value::TokenValue
    first::Int
    last::Int
end

struct Context
    source::String
    pos::Mut{Int}
    length::Int
    tokens::Vector{Token}
    captures::Vector{UnitRange{Int}}
    Context(c::Context, len::Int) = new(c.source, c.pos, len, c.tokens, c.captures)
    Context(s::AbstractString) = new(s, Mut(1), lastindex(s), [], [])
end

isdone(ctx::Context) = ctx.pos[] > ctx.length

struct State{s} end

const NULL_RANGE = 0:0
valid(r::AbstractRange) = r !== NULL_RANGE

function nullmatch(r::Regex, ctx::Context)
    source = ctx.source
    index = ctx.pos[]
    m = match(r, source[index:end])
    if m === nothing
        return NULL_RANGE
    else
        if length(m.captures) > 0
            length(ctx.captures) < length(m.captures) && resize!(ctx.captures, length(m.captures))
            for i = 1:length(m.captures)
                ctx.captures[i] = (m.captures[i] === nothing) ? NULL_RANGE :
                    (index + m.offsets[i] - 1 : index + m.offsets[i] + ncodeunits(m.captures[i]) - 2)
            end
        end
        return index : index + ncodeunits(m.match) - 1
    end
end
nullmatch(f::Function, ctx::Context) = f(ctx)

function update!(ctx::Context, range::AbstractRange, token::TokenValue)
    pos = prevind(ctx.source, ctx.pos[] + length(range))
    if !isempty(ctx.tokens) && ctx.tokens[end].value == token
        ctx.tokens[end] = Token(token, ctx.tokens[end].first, pos)
    else
        ctx.pos[] <= pos && push!(ctx.tokens, Token(token, ctx.pos[], pos))
    end
    ctx.pos[] = nextind(ctx.source, pos)
    return ctx
end

function update!(ctx::Context, range::AbstractRange, lexer::Type, state = State{:root}())
    pos = ctx.pos[] + length(range)
    lex!(Context(ctx, last(range)), lexer, state)
    ctx.pos[] = pos
    return ctx
end

function error!(ctx::Context)
    push!(ctx.tokens, Token(Tokens.ERROR, ctx.pos[], ctx.pos[]))
    ctx.pos[] = nextind(ctx.source, ctx.pos[])
    return ctx
end

lex(s::AbstractString, l::Type{T}) where {T <: AbstractLexer} = lex!(Context(s), l, State{:root}())

function metadata end
function lex! end

# Load all supertypes' metadata.
getdata(T) = getdata!(IdDict(), T)
getdata!(d, ::Type{AbstractLexer}) = d
getdata!(d, lxr) = (getdata!(d, supertype(lxr)); d[lxr] = metadata(lxr); d)

struct LexerData
    name::String
    aliases::Vector{String}
    filenames::Vector{String}
    description::String
    comments::String
    tokens::Dict{Symbol, Vector{Any}}

    function LexerData(dict::Dict)
        name = get(dict, :name, "")
        aliases = get(dict, :aliases, String[])
        filenames = get(dict, :filenames, String[])
        description = get(dict, :description, "")
        comments = get(dict, :comments, "")
        tokens = get(dict, :tokens, Dict{Symbol, Vector{Any}}())
        return new(name, aliases, filenames, description, comments, tokens)
    end
end

function compile_lexer(mod::Module, T)
    data = metadata(T)
    for state in keys(data.tokens)
        func = quote
            function $(Compiler).lex!(ctx::$(Context), ::Type{$T}, ::$(State{state}))
                S = $(Meta.quot(state))
                $(compile(T, state, getdata(T)))
            end
        end
        Core.eval(mod, func)
        Base.precompile(lex!, (Context, Type{T}, State{state}))
    end
end

function getrules(T::Type, S::Symbol, data::IdDict)
    haskey(data, T) || return Any[]
    lexer = data[T]
    haskey(lexer.tokens, S) ? lexer.tokens[S] : return Any[]
end

function compile(T::Type, S::Symbol, data::IdDict)
    quote
        T = $T
        while !$(Compiler).isdone(ctx)
            $(compile_rules(T, S, data, getrules(T, S, data)))
            $(Compiler).error!(ctx)
        end
        ctx
    end
end

function compile_rules(T::Type, S::Symbol, data::IdDict, rules::Vector)
    ex = Expr(:block)
    for each in getrules(T, S, data)
        push!(ex.args, compile_rule(T, S, data, each))
    end
    return ex
end

function compile_rule(T, S, data, rule::Symbol)
    ty, st = rule === :__inherit__ ? (supertype(T), S) : (T, rule)
    # return compile_rules(T, S, data, getrules(ty, st, data))
    ex = Expr(:block)
    for each in getrules(ty, st, data)
        push!(ex.args, compile_rule(T, S, data, each))
    end
    return ex
end
compile_rule(T, S, data, rule::Tuple) = compile_match(T, S, data, rule...)

function compile_match(T, S, data, match, bindings, target = :__none__)
    quote
        let range = $(Compiler).nullmatch($(prepare_match(match)), ctx)
            if $(Compiler).valid(range)
                $(prepare_bindings(bindings))
                $(prepare_target(T, S, target))
                continue
            end
        end
    end
end

# Regex matchers need to be 'left-anchored' with `\G` to work correctly.
prepare_match(r::Regex) = Regex("\\G$(r.pattern)", r.compile_options, r.match_options)
prepare_match(f::Function) = f

function prepare_bindings(tuple::Tuple)
    block = Expr(:block)
    for (nth, element) in enumerate(tuple)
        push!(block.args, prepare_binding(element, :(ctx.captures[$(nth)])))
    end
    return block
end
prepare_bindings(other) = prepare_binding(other, :range)

# A token such as `TEXT` or `NUMBER`.
prepare_binding(t::TokenValue, range) = :($(Compiler).update!(ctx, $range, $t))
# Call different lexer's `:root` state.
prepare_binding(::Type{L}, range) where {L} = :($(Compiler).update!(ctx, $range, $L, $(State{:root}())))
# Call current lexer in state `S`.
prepare_binding(S::Symbol, range) = :($(Compiler).update!(ctx, $range, T, $(State{S}())))
# Call different lexer's state `p.second`.
prepare_binding(p::Pair, range) = :($(Compiler).update!(ctx, $range, $(first(p)), $(State{last(p)}())))

# Do nothing, pop the state, push another one on, or enter a new one entirely.
function prepare_target(T, s::Symbol, target::Symbol)
    target === :__none__ && return Expr(:block)
    target === :__pop__  && return Expr(:break)
    state = target === :__push__ ? s : target
    return :($(Compiler).lex!(ctx, $(T), $(State{state}())))
end

# A tuple of states to enter must be done in 'reverse' order.
function prepare_target(T, s::Symbol, ts::Tuple)
    out = Expr(:block)
    for t in ts
        pushfirst!(out.args, prepare_target(T, s, t))
    end
    return out
end

# Useful function for checking tokens.
function debug(io::IO, src::AbstractString, lexer)
    tokens = lex(src, lexer).tokens
    padding = mapreduce(t -> length(string(t.value)), max, tokens, init=0)
    for each in tokens
        print(io, lpad(string(each.value), padding), " := ")
        println(io, repr(SubString(src, each.first, each.last)))
    end
end
debug(src::AbstractString, lexer) = debug(stdout, src, lexer)

end # module


text:
##Scoping Exercises

# Scoping Example

x=5; y=7; #Defined globally
function scopeTest(z)
  x += z #Changes global value
  y = Vector{Float64}(1) #Declares a variable, local scope
  y[1] = 2
  return x + y + z
end

# Caution Example

function f1()
  @parallel for i = 1:100
    var = 10
    if var < 100
      var = var + 1
    end
  end
  var = 100 + 10
end
f1()
function f2()
  @parallel for i = 1:100
    var = 10
    if var < 100
      var = var + 1
    end
  end
end
f2()


text:
using ConvInsight
using Base.Test
using HDF5

@testset "LogFile" begin
    lf = Logfile("foo !bar", tempdir()) # custom dir
    @test lf.path == joinpath(tempdir(), "foobar.h5")
    @test lf.name == "foo !bar"
    @test lf.name == h5open(lf.path, "r") do root
        read(attrs(root)["name"])
    end
    rm(lf.path)
    path = tempname() # custom filename
    lf = Logfile("foo !bar", path)
    @test lf.path == path * ".h5"
    @test lf.name == "foo !bar"
    @test lf.name == h5open(lf.path, "r") do root
        read(attrs(root)["name"])
    end
    rm(lf.path)
end

@testset "metadata" begin
    lf = Logfile("testfile", tempdir()) # custom dir
    log_metadata!(lf, foo = 2.3, bar = 4, baz = "5")
    h5open(lf.path, "r") do root
        @test 4 == length(names(attrs(root)))
        @test 2.3 === read(attrs(root)["foo"])
        @test 4 === read(attrs(root)["bar"])
        @test "5" == read(attrs(root)["baz"])
    end
    log_metadata!(lf, Dict("bar" => 6, "baz" => 5))
    h5open(lf.path, "r") do root
        @test 4 == length(names(attrs(root)))
        @test 2.3 === read(attrs(root)["foo"])
        @test 6 === read(attrs(root)["bar"])
        @test 5 == read(attrs(root)["baz"])
    end
    rm(lf.path)
end

@testset "timeseries" begin
    lf = Logfile("testfile", tempdir()) # custom dir
    log_timeseries!(lf, 2, int = 2)
    log_timeseries!(lf, 5, Dict("acc" => 0.2, "int" => 1))
    log_timeseries!(lf, 6, acc = 0.5, int = 0)
    h5open(lf.path, "r") do root
        @test 2 == length(names(root["timeseries"]))
        @test [2,5,6] == read(root["timeseries/int/steps"])
        @test [2,1,0] == read(root["timeseries/int/value"])
        @test read(root["timeseries/int/value"]) isa Vector{Int}
        @test [5,6] == read(root["timeseries/acc/steps"])
        @test [0.2,0.5] == read(root["timeseries/acc/value"])
        @test read(root["timeseries/acc/value"]) isa Vector{Float64}
        @test read(root["timeseries/int/time"])[2:3] == read(root["timeseries/acc/time"])
    end
    rm(lf.path)
end


text:
push!(LOAD_PATH, "/home/hebertc1/Installations/Julia")
using Mea
using JSON

paramsfile = "statsparams0.json"
beta_ = JSON.parsefile(paramsfile)["beta"][1]

maxevals = 300_000
cutoff = 100.0

for ii in 0:10

try
	fname = "self_ctow" * string(ii) * ".dat"
	if !isfile(fname)
		break
	end
	foutdos = "dosjulia" * string(ii) * ".dat"
	foutdoscuba = "dosjulia_cuba" * string(ii) * ".dat"
	foutdostrace = "dosjulia_trace" * string(ii) * ".dat"
	foutdoscum = "dosjulia_cum" * string(ii) * ".dat"

	modelvec = Mea.Periodize.buildmodelvec(fname, paramsfile)

	coefs = Mea.Transport.coefstrans(modelvec, beta_, cutoff=cutoff, fout_name=foutdos, maxevals=maxevals)
	coefs_cuba = Mea.Transport.coefstrans(modelvec, beta_, cutoff=cutoff, fout_name=foutdoscuba, maxevals=maxevals, libintegrator="cuba")
	coefs_trace = Mea.Transport.coefstrans(modelvec, beta_, cutoff=cutoff, fout_name=foutdostrace, maxevals=maxevals,
										   libintegrator="cubature", fctper="make_akw2trace")
	coefs_cum =  Mea.Transport.coefstrans(modelvec, beta_, cutoff=cutoff, fout_name=foutdoscum, maxevals=maxevals,
											libintegrator="cubature", fctper="make_akw2cum")

	println("\n iteration = ", ii)
	println("coefs = ", coefs)
	println("coefs_cuba = ", coefs_cuba)
	println("coefs_trace = ", coefs_trace)
	println("coefs_cum = ", coefs_cum)

catch exc
	println("caught exception: $exc")
end

end


text:
export lorenz63!, setup_lorenz63, generate_lorenz63, benchmark_lorenz63, benchmark_srmf_lorenz63, benchmark_sadaptivermf_lorenz63

"""
    lorenz63!(du,u,p,t)

Compute in-place the right-hand-side of the Lorenz-63 system for a state `u` at time `t`,
and store it in `du`. `p` is vector of user-defined parameters.
"""
function lorenz63!(du,u,p,t)
    du[1] = 10.0*(u[2]-u[1])
    du[2] = u[1]*(28.0-u[3]) - u[2]
    du[3] = u[1]*u[2] - (8/3)*u[3]
    return du
end

function generate_lorenz63(model::Model, x0::Array{Float64,1}, J::Int64)

    @assert model.Nx == size(x0,1) "Error dimension of the input"
    xt = zeros(model.Nx,J)
    x = deepcopy(x0)
    yt = zeros(model.Ny,J)
    tt = zeros(J)

    t0 = 0.0

    step = ceil(Int, model.Δtobs/model.Δtdyn)
    tspan = (t0, t0 + model.Δtobs)
    prob = ODEProblem(model.F.f,x,tspan)

    for i=1:J
    	# Run dynamics and save results
    	tspan = (t0 + (i-1)*model.Δtobs, t0 + i*model.Δtobs)
    	prob = remake(prob, tspan = tspan)

    	sol = solve(prob, Tsit5(), dt = model.Δtdyn, adaptive = false, dense = false, save_everystep = false)
    	x .= deepcopy(sol.u[end])
    	# for j=1:step
    	# 	t = t0 + (i-1)*algo.Δtobs+(j-1)*algo.Δtdyn
        # 	_, x = model.f(t+(i-1)*model.Δtdyn, x)
    	# end
    	model.ϵx(x)

    	# Collect observations
    	tt[i] = deepcopy(i*model.Δtobs)
    	xt[:,i] = deepcopy(x)
    	yt[:,i] = deepcopy(model.F.h(x, tt[i]))
        # model.ϵy(yt[:,i])
		yt[:,i] .+= model.ϵy.m + model.ϵy.σ*randn(model.Ny)
    end
    	return SyntheticData(tt, model.Δtdyn, x0, xt, yt)
end

function spin_lorenz63(model::Model, data::SyntheticData, Ne::Int64, path::String)
	@assert path[1]=='/' && path[end]=='/' "This function expects a / at the extremities of path"

	# Set initial condition
	X = zeros(model.Ny + model.Nx, Ne)
	X[model.Ny+1:model.Ny+model.Nx,:] .= rand(model.π0, Ne)#sqrt(model.C0)*randn(model.Nx, Ne) .+ model.m0

	J = model.Tspinup
	t0 = 0.0
	F = model.F
	enkf = StochEnKF(x->x, model.ϵy, model.Δtdyn, model.Δtobs, false, false)

	statehist = seqassim(F, data, J, model.ϵx, enkf, X, model.Ny, model.Nx, t0)

    save(path*"set_up_Ne"*string(Ne)*".jld", "state", statehist, "Ne", Ne, "x0", data.x0, "tt", data.tt, "xt", data.xt, "yt", data.yt)

    # return statehist
	_,_,rmse_mean,_ = metric_hist(rmse, data.xt[:,1:J], statehist[2:end])
	println("Ne "*string(Ne)* " RMSE: "*string(rmse_mean))
	# Save data
	save(path*"set_up_Ne"*string(Ne)*".jld", "X", statehist[end], "Ne", Ne, "x0", data.x0, "tt", data.tt, "xt", data.xt, "yt", data.yt)
end

function setup_lorenz63(path::String, Ne_array::Array{Int64,1})
    Nx = 3
    Ny = 3
    Δtdyn = 0.05
    Δtobs = 0.1

    σx = 1e-6
    σy = 2.0

    ϵx = AdditiveInflation(Nx, zeros(Nx), σx)
    ϵy = AdditiveInflation(Ny, zeros(Ny), σy)
    tspinup = 200.0
    Tspinup = 2000
    tmetric = 400.0
    Tmetric = 4000
    t0 = 0.0
    tf = 600.0
    Tf = 6000

    Tburn = 2000
    Tstep = 4000
    Tspinup = 2000

    f = lorenz63!
    h(x, t) = x
    # Create a local version of the observation operator
    h(x, t, idx) = x[idx]
	F = StateSpace(lorenz63!, h)

    model = Model(Nx, Ny, Δtdyn, Δtobs, ϵx, ϵy, MvNormal(zeros(Nx), Matrix(1.0*I, Nx, Nx)), Tburn, Tstep, Tspinup, F);

    # Set initial condition
    x0 = rand(model.π0)
    # x0 = [0.645811242103507;  -1.465126216973632;   0.385227725149822];

    # Run dynamics and generate data
    data = generate_lorenz63(model, x0, model.Tspinup+model.Tstep);

    for Ne in Ne_array
        spin_lorenz63(model, data, Ne, path)
    end

    return model, data
end

function benchmark_lorenz63(model::Model, data::SyntheticData, path::String, Ne_array::Array{Int64,1}, β_array::Array{Float64,1})
@assert path[1]=='/' && path[end]=='/' "This function expects a / at the extremities of path"

#Store all the metric per number of ensemble members
metric_list = []

@showprogress for Ne in Ne_array
    metric_Ne = Metrics[]
    for β in β_array
    @show Ne, β
    # Load file
    X0 = load(path*"set_up_Ne"*string(Ne)*".jld", "X")

    X = zeros(model.Ny + model.Nx, Ne)
    X[model.Ny+1:model.Ny+model.Nx,:] .= copy(X0)
    J = model.Tstep
    t0 = model.Tspinup*model.Δtobs
    F = model.F
    enkf = StochEnKF(x->x, model.ϵy, model.Δtdyn, model.Δtobs, false, false)

    # Use this multi-additive inflation
    ϵx = MultiAddInflation(model.Nx, β, zeros(model.Nx), model.ϵx.Σ, model.ϵx.σ)

    # @time enshist = seqassim(dyn, data, J, ϵx, enkf, ens, t0)
	@time statehist = seqassim(F, data, J, model.ϵx, enkf, X, model.Ny, model.Nx, t0);

    metric = post_process(data, model, J, statehist)
    push!(metric_Ne, deepcopy(metric))
    println("Ne "*string(Ne)*"& β "*string(β)*" RMSE: "*string(metric.rmse_mean))
    end
    push!(metric_list, deepcopy(metric_Ne))
end

return metric_list
end

# Routine to benchmark the stochastic radial map filter
function benchmark_srmf_lorenz63(model::Model, data::SyntheticData, path::String, Ne_array::Array{Int64,1}, β_array::Array{Float64,1}, p::Int64)
@assert path[1]=='/' && path[end]=='/' "This function expects a / at the extremities of path"

#Store all the metric per number of ensemble members
metric_hist = []

@showprogress for Ne in Ne_array
    metric_Ne = Metrics[]
    for β in β_array

	@show Ne, β
    # Load file
    X0 = load(path*"set_up_Ne"*string(Ne)*".jld", "X")

    X = zeros(model.Ny + model.Nx, Ne)
    X[model.Ny+1:model.Ny+model.Nx,:] .= copy(X0)

    J = model.Tstep
    t0 = model.Tspinup*model.Δtobs
    F = model.F
	dist = Float64.(metric_lorenz(model.Nx))
	idx = vcat(collect(1:model.Ny)',collect(1:model.Ny)')

    order = [[-1], [p; p], [-1; p; 0], [-1; p; p; 0]]

	γ = 2.0
	λ = 0.0
	δ = 1e-8
	κ = 10.0

	smf = SparseRadialSMF(x->x, F.h, β, model.ϵy, order, γ, λ, δ, κ,
                      model.Ny, model.Nx, Ne,
                      model.Δtdyn, model.Δtobs,
                      dist, idx; islocalized = true)

    @time statehist = seqassim(F, data, J, model.ϵx, smf, X, model.Ny, model.Nx, t0);

    metric = post_process(data, model, J, statehist)
    push!(metric_Ne, deepcopy(metric))
    println("Ne "*string(Ne)*"& β "*string(β)*" RMSE: "*string(metric.rmse_mean))
    end
    push!(metric_hist, deepcopy(metric_Ne))
end

return metric_hist
end

# Routine to benchmark the stochastic adaptive radial map filter
function benchmark_sadaptivermf_lorenz63(model::Model, data::SyntheticData, path::String, Ne_array::Array{Int64,1}, β_array::Array{Float64,1}, p::Int64)
@assert path[1]=='/' && path[end]=='/' "This function expects a / at the extremities of path"

# Perform a free-run of the model to identify the structure

xfreerun = rand(model.π0)
tfreerun = 20000
Tfreerun = ceil(Int64, tfreerun/model.Δtobs)
data_freerun = generate_lorenz63(model, xfreerun, Tfreerun)

Tdiscard = 2000
Δdiscard = 40

#Store all the metric per number of ensemble members
metric_hist = []

@showprogress for Ne in Ne_array
    metric_Ne = Metrics[]
    for β in β_array

	@show Ne, β

	γ = 2.0
	λ = 0.0
	δ = 1e-8
	κ = 10.0

	J = model.Tstep
	t0 = model.Tspinup*model.Δtobs
	F = model.F
	dist = Float64.(metric_lorenz(model.Nx))
	idx = vcat(collect(1:model.Ny)',collect(1:model.Ny)')

	Slist = SparseRadialMap[]
		for i=1:model.Ny
			idx1, idx2 = idx[:,i]
			perm = sortperm(view(dist,:,idx2))
			Xi = vcat(data_freerun.yt[i:i,Tdiscard:Δdiscard:end], data_freerun.xt[perm, Tdiscard:Δdiscard:end])
			Si = SparseRadialMap(Xi, -1; λ = λ, δ = δ, γ = γ)
			poff = p
			order = [p; 0; 0]
			# maxfeatures = ceil(Int64, (sqrt(Ne)-(findmin(order)[2]+1))/(poff+1))

			optimize(Si, Xi, poff, order, 2; apply_rescaling = true, start = 2)#, maxfeatures = maxfeatures)
			push!(Slist, Si)
		end
    # Load file
    X0 = load(path*"set_up_Ne"*string(Ne)*".jld", "X")

    X = zeros(model.Ny + model.Nx, Ne)
    X[model.Ny+1:model.Ny+model.Nx,:] .= copy(X0)

    smf = AdaptiveSparseRadialSMF(x->x, F.h, β, model.ϵy, Slist,
                        model.Ny, model.Nx,
                        model.Δtdyn, model.Δtobs, Inf,
                        dist, idx, zeros(model.Nx+1, Ne), false, true)
    @time statehist = seqassim(F, data, J, model.ϵx, smf, X, model.Ny, model.Nx, t0);

    metric = post_process(data, model, J, statehist)
    push!(metric_Ne, deepcopy(metric))
    println("Ne "*string(Ne)*"& β "*string(β)*" RMSE: "*string(metric.rmse_mean))
    end
    push!(metric_hist, deepcopy(metric_Ne))
end

return metric_hist
end


text:
module Pivots
  using DataFrames
  using Docile
  import DataFrames: groupby
  using Tables
  import TableInterface:
    Nullable, get,
    Table, Point, Box, CellRange, Layout, AbstractStyleElement, AbstractPresentationStyleElement,
    CartesianStyleElement, ExpandStyleElement, UniformStyleElement,
    ExpandDataElement, CartesianDataElement
  import Iterators: product
  import Formatting: sprintf1, format

  export Pivot, PivotMetadata, totable, summarize

  include("group.jl")
  include("pivot.jl")
  include("table.jl")
end # module

max_stars_repo_name: cpritcha/Pivots

max_issues_repo_name: cpritcha/Pivots

max_forks_repo_name: cpritcha/Pivots