#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
char *cdiStringError(int);
int /*<<< orphan*/ fprintf(int /*<<< orphan*/, char *, char *);
int /*<<< orphan*/ free(double *);
int gridCreate(int, int);
int /*<<< orphan*/ gridDefXsize(int, int);
int /*<<< orphan*/ gridDefYsize(int, int);
scalar_t__ gridInqSize(int);
int /*<<< orphan*/ gridInqType(int);
int institutDef(int, int /*<<< orphan*/, int /*<<< orphan*/ *,
                int /*<<< orphan*/ *);
scalar_t__ malloc(size_t);
int /*<<< orphan*/ memset(double *, int /*<<< orphan*/, size_t);
int /*<<< orphan*/ stderr;
int /*<<< orphan*/ streamClose(int);
int /*<<< orphan*/ streamDefTimestep(int, int);
int /*<<< orphan*/ streamDefVlist(int, int);
int streamInqFiletype(int);
int streamInqTimestep(int, int);
int streamInqVlist(int);
int streamOpenWrite(char *, int);
int /*<<< orphan*/ streamReadVar(int, int, double *, int *);
int /*<<< orphan*/ streamWriteVar(int, int, double *, int);
int taxisCreate(int);
int /*<<< orphan*/ taxisInqVdate(int);
int /*<<< orphan*/ taxisInqVtime(int);
int vlistCreate();
int /*<<< orphan*/ vlistDefInstitut(int, int);
int /*<<< orphan*/ vlistDefTaxis(int, int);
int vlistDefVar(int, int, int, int);
int /*<<< orphan*/ vlistDefVarEnsemble(int, int, int, int, int);
int vlistInqTaxis(int);
int /*<<< orphan*/ vlistInqVarCode(int, int);
int /*<<< orphan*/ vlistInqVarEnsemble(int, int, int *, int *, int *);
int vlistInqVarGrid(int, int);
int /*<<< orphan*/ vlistInqVarMissval(int, int);
int vlistInqVarZaxis(int, int);
int vlistNvars(int);
int zaxisCreate(int /*<<< orphan*/, int);
int /*<<< orphan*/ zaxisInqLevel(int, int);
int zaxisInqSize(int);
int main(void) {
  char fname[] = "test_ens.grb2";
  int filetype = 2;
  int nlat = 18, nlon = 2 * nlat;
  double *data = NULL;
  int nlevel;
  int varID;
  int streamID1, streamID2;
  int gridID, zaxisID;
  int nrecs, nvars;
  int tsID;
  int levelID;
  int vlistID, taxisID;
  int nmiss;
  int instID;
  int i1, i2, i3;
  size_t datasize = (size_t)nlon * (size_t)nlat;
  data = (double *)malloc(datasize * sizeof(double));
  memset(data, 0, datasize * sizeof(double));
  gridID = gridCreate(2, (int)datasize);
  gridDefXsize(gridID, nlon);
  gridDefYsize(gridID, nlat);
  zaxisID = zaxisCreate(0, 1);
  instID = institutDef(252, 0, NULL, NULL);
  vlistID = vlistCreate();
  varID = vlistDefVar(vlistID, gridID, zaxisID, 1);
  vlistDefVarEnsemble(vlistID, varID, 1, 2, 3);
  vlistInqVarEnsemble(vlistID, varID, &i1, &i2, &i3);
  vlistDefInstitut(vlistID, instID);
  taxisID = taxisCreate(1);
  vlistDefTaxis(vlistID, taxisID);
  streamID1 = streamOpenWrite(fname, filetype);
  if (streamID1 < 0) {
    fprintf(stderr, "Open failed on %s\n", fname);
    fprintf(stderr, "%s\n", cdiStringError(streamID1));
    return (-1);
  }
  streamDefVlist(streamID1, vlistID);
  (void)streamDefTimestep(streamID1, 0);
  streamWriteVar(streamID1, varID, data, 0);
  return (0);
  vlistID = streamInqVlist(streamID1);
  filetype = streamInqFiletype(streamID1);
  streamID2 = streamOpenWrite(fname, filetype);
  if (streamID2 < 0) {
    fprintf(stderr, "Open failed on %s\n", fname);
    fprintf(stderr, "%s\n", cdiStringError(streamID2));
    return (-1);
  }
  streamDefVlist(streamID2, vlistID);
  nvars = vlistNvars(vlistID);
  for (varID = 0; varID < nvars; varID++) {
    int gridID = vlistInqVarGrid(vlistID, varID);
    int zaxisID = vlistInqVarZaxis(vlistID, varID);
    size_t gridsize = (size_t)gridInqSize(gridID);
    size_t nlevel = (size_t)zaxisInqSize(zaxisID);
    if (gridsize * nlevel > datasize)
      datasize = gridsize * nlevel;
  }
  data = (double *)malloc(datasize * sizeof(double));
  memset(data, 0, datasize * sizeof(double));
  taxisID = vlistInqTaxis(vlistID);
  tsID = 0;
  while ((nrecs = streamInqTimestep(streamID1, tsID))) {
    taxisInqVdate(taxisID);
    taxisInqVtime(taxisID);
    streamDefTimestep(streamID2, tsID);
    for (varID = 0; varID < nvars; varID++) {
      streamReadVar(streamID1, varID, data, &nmiss);
      vlistInqVarCode(vlistID, varID);
      gridID = vlistInqVarGrid(vlistID, varID);
      zaxisID = vlistInqVarZaxis(vlistID, varID);
      gridInqType(gridID);
      gridInqSize(gridID);
      nlevel = zaxisInqSize(zaxisID);
      vlistInqVarMissval(vlistID, varID);
      for (levelID = 0; levelID < nlevel; levelID++) {
        zaxisInqLevel(zaxisID, levelID);
      }
      streamWriteVar(streamID2, varID, data, nmiss);
    }
    tsID++;
  }
  free(data);
  streamClose(streamID2);
  streamClose(streamID1);
  return (0);
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
movl   $0x0,-0x4(%rbp)
mov    0xda7(%rip),%rax
mov    %rax,-0x12(%rbp)
mov    0xda5(%rip),%eax
mov    %eax,-0xa(%rbp)
mov    0xd9f(%rip),%ax
mov    %ax,-0x6(%rbp)
movl   $0x2,-0x18(%rbp)
movl   $0x12,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
shl    $0x1,%eax
mov    %eax,-0x20(%rbp)
movq   $0x0,-0x28(%rbp)
movslq -0x20(%rbp),%rax
movslq -0x1c(%rbp),%rcx
imul   %rcx,%rax
mov    %rax,-0x78(%rbp)
mov    -0x78(%rbp),%rdi
shl    $0x3,%rdi
call   10e0 <malloc@plt>
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rdi
mov    -0x78(%rbp),%rdx
shl    $0x3,%rdx
xor    %esi,%esi
call   1080 <memset@plt>
mov    -0x78(%rbp),%rax
mov    %eax,%esi
mov    $0x2,%edi
call   1070 <gridCreate@plt>
mov    %eax,-0x3c(%rbp)
mov    -0x3c(%rbp),%edi
mov    -0x20(%rbp),%esi
call   10f0 <gridDefXsize@plt>
mov    -0x3c(%rbp),%edi
mov    -0x1c(%rbp),%esi
call   1110 <gridDefYsize@plt>
xor    %edi,%edi
mov    $0x1,%esi
call   1100 <zaxisCreate@plt>
mov    %eax,-0x40(%rbp)
mov    $0xfc,%edi
xor    %esi,%esi
xor    %eax,%eax
mov    %eax,%ecx
mov    %rcx,%rdx
call   1040 <institutDef@plt>
mov    %eax,-0x60(%rbp)
mov    $0x0,%al
call   1140 <vlistCreate@plt>
mov    %eax,-0x54(%rbp)
mov    -0x54(%rbp),%edi
mov    -0x3c(%rbp),%esi
mov    -0x40(%rbp),%edx
mov    $0x1,%ecx
call   1030 <vlistDefVar@plt>
mov    %eax,-0x30(%rbp)
mov    -0x54(%rbp),%edi
mov    -0x30(%rbp),%esi
mov    $0x1,%edx
mov    $0x2,%ecx
mov    $0x3,%r8d
call   10b0 <vlistDefVarEnsemble@plt>
mov    -0x54(%rbp),%edi
mov    -0x30(%rbp),%esi
lea    -0x64(%rbp),%rdx
lea    -0x68(%rbp),%rcx
lea    -0x6c(%rbp),%r8
call   1120 <vlistInqVarEnsemble@plt>
mov    -0x54(%rbp),%edi
mov    -0x60(%rbp),%esi
call   1130 <vlistDefInstitut@plt>
mov    $0x1,%edi
call   1150 <taxisCreate@plt>
mov    %eax,-0x58(%rbp)
mov    -0x54(%rbp),%edi
mov    -0x58(%rbp),%esi
call   1050 <vlistDefTaxis@plt>
lea    -0x12(%rbp),%rdi
mov    -0x18(%rbp),%esi
call   10a0 <streamOpenWrite@plt>
mov    %eax,-0x34(%rbp)
cmpl   $0x0,-0x34(%rbp)
jge    13eb <main+0x1ab>
mov    0x2c39(%rip),%rax
mov    (%rax),%edi
lea    -0x12(%rbp),%rdx
lea    0xc5a(%rip),%rsi
call   10c0 <fprintf@plt>
mov    0x2c20(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x7c(%rbp)
mov    -0x34(%rbp),%edi
call   10d0 <cdiStringError@plt>
mov    -0x7c(%rbp),%edi
mov    %rax,%rdx
lea    0xc43(%rip),%rsi
call   10c0 <fprintf@plt>
movl   $0xffffffff,-0x4(%rbp)
jmp    1418 <main+0x1d8>
mov    -0x34(%rbp),%edi
mov    -0x54(%rbp),%esi
call   1060 <streamDefVlist@plt>
mov    -0x34(%rbp),%edi
xor    %esi,%esi
call   1090 <streamDefTimestep@plt>
mov    -0x34(%rbp),%edi
mov    -0x30(%rbp),%esi
mov    -0x28(%rbp),%rdx
xor    %ecx,%ecx
call   1160 <streamWriteVar@plt>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
movabs $0x326272672e736e,%rax
mov    %rax,0xe(%rsp)
movabs $0x736e655f74736574,%rax
65 6e 73
mov    %rax,0x8(%rsp)
mov    $0x1440,%edi
call   10e0 <malloc@plt>
mov    %rax,%r15
xor    %r14d,%r14d
mov    $0x1440,%edx
mov    %rax,%rdi
xor    %esi,%esi
call   1080 <memset@plt>
mov    $0x2,%edi
mov    $0x288,%esi
call   1070 <gridCreate@plt>
mov    %eax,%ebp
mov    %eax,%edi
mov    $0x24,%esi
call   10f0 <gridDefXsize@plt>
mov    %ebp,%edi
mov    $0x12,%esi
call   1110 <gridDefYsize@plt>
xor    %edi,%edi
mov    $0x1,%esi
call   1100 <zaxisCreate@plt>
mov    %eax,%r13d
mov    $0xfc,%edi
xor    %esi,%esi
xor    %edx,%edx
xor    %ecx,%ecx
call   1040 <institutDef@plt>
mov    %eax,%r12d
xor    %eax,%eax
call   1140 <vlistCreate@plt>
mov    %eax,%ebx
mov    %eax,%edi
mov    %ebp,%esi
mov    %r13d,%edx
mov    $0x1,%ecx
call   1030 <vlistDefVar@plt>
mov    %eax,%r13d
mov    %ebx,%edi
mov    %eax,%esi
mov    $0x1,%edx
mov    $0x2,%ecx
mov    $0x3,%r8d
call   10b0 <vlistDefVarEnsemble@plt>
lea    0x24(%rsp),%rdx
lea    0x20(%rsp),%rcx
lea    0x1c(%rsp),%r8
mov    %ebx,%edi
mov    %r13d,%esi
call   1120 <vlistInqVarEnsemble@plt>
mov    %ebx,%edi
mov    %r12d,%esi
call   1130 <vlistDefInstitut@plt>
mov    $0x1,%edi
call   1150 <taxisCreate@plt>
mov    %ebx,%edi
mov    %eax,%esi
call   1050 <vlistDefTaxis@plt>
lea    0x8(%rsp),%rdi
mov    $0x2,%esi
call   10a0 <streamOpenWrite@plt>
mov    %eax,%ebp
test   %eax,%eax
js     137a <main+0x13a>
mov    %ebp,%edi
mov    %ebx,%esi
call   1060 <streamDefVlist@plt>
mov    %ebp,%edi
xor    %esi,%esi
call   1090 <streamDefTimestep@plt>
mov    %ebp,%edi
mov    %r13d,%esi
mov    %r15,%rdx
xor    %ecx,%ecx
call   1160 <streamWriteVar@plt>
jmp    13b4 <main+0x174>
mov    0x2c5f(%rip),%rbx
mov    (%rbx),%edi
lea    0xc84(%rip),%rsi
lea    0x8(%rsp),%rdx
call   10c0 <fprintf@plt>
mov    (%rbx),%ebx
mov    %ebp,%edi
call   10d0 <cdiStringError@plt>
lea    0xc79(%rip),%rsi
mov    %ebx,%edi
mov    %rax,%rdx
call   10c0 <fprintf@plt>
mov    $0xffffffff,%r14d
mov    %r14d,%eax
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@__const.main.fname = [14 x i8] c"test_ens.grb2\00"
@stderr = global i32 0
@.str = [19 x i8] c"Open failed on %s\0A\00"
@.str.1 = [4 x i8] c"%s\0A\00"
define i32 @main() {
%1 = alloca i32
%2 = alloca [14 x i8]
%3 = alloca i32
%4 = alloca i32
%5 = alloca i32
%6 = alloca double*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca i32
%17 = alloca i32
%18 = alloca i32
%19 = alloca i32
%20 = alloca i32
%21 = alloca i32
%22 = alloca i32
%23 = alloca i32
%24 = alloca i64
store i32 0, i32* %1
%25 = bitcast [14 x i8]* %2 to i8*
store i32 2, i32* %3
store i32 18, i32* %4
%26 = load i32, i32* %4
%27 = mul nsw i32 2, %26
store i32 %27, i32* %5
store double* null, double** %6
%28 = load i32, i32* %5
%29 = sext i32 %28 to i64
%30 = load i32, i32* %4
%31 = sext i32 %30 to i64
%32 = mul i64 %29, %31
store i64 %32, i64* %24
%33 = load i64, i64* %24
%34 = mul i64 %33, 8
%35 = call i64 @malloc(i64 %34)
%36 = inttoptr i64 %35 to double*
store double* %36, double** %6
%37 = load double*, double** %6
%38 = load i64, i64* %24
%39 = mul i64 %38, 8
%40 = call i32 @memset(double* %37, i32 0, i64 %39)
%41 = load i64, i64* %24
%42 = trunc i64 %41 to i32
%43 = call i32 @gridCreate(i32 2, i32 %42)
store i32 %43, i32* %11
%44 = load i32, i32* %11
%45 = load i32, i32* %5
%46 = call i32 @gridDefXsize(i32 %44, i32 %45)
%47 = load i32, i32* %11
%48 = load i32, i32* %4
%49 = call i32 @gridDefYsize(i32 %47, i32 %48)
%50 = call i32 @zaxisCreate(i32 0, i32 1)
store i32 %50, i32* %12
%51 = call i32 @institutDef(i32 252, i32 0, i32* null, i32* null)
store i32 %51, i32* %20
%52 = call i32 (...) @vlistCreate()
store i32 %52, i32* %17
%53 = load i32, i32* %17
%54 = load i32, i32* %11
%55 = load i32, i32* %12
%56 = call i32 @vlistDefVar(i32 %53, i32 %54, i32 %55, i32 1)
store i32 %56, i32* %8
%57 = load i32, i32* %17
%58 = load i32, i32* %8
%59 = call i32 @vlistDefVarEnsemble(i32 %57, i32 %58, i32 1, i32 2, i32 3)
%60 = load i32, i32* %17
%61 = load i32, i32* %8
%62 = call i32 @vlistInqVarEnsemble(i32 %60, i32 %61, i32* %21, i32* %22, i32* %23)
%63 = load i32, i32* %17
%64 = load i32, i32* %20
%65 = call i32 @vlistDefInstitut(i32 %63, i32 %64)
%66 = call i32 @taxisCreate(i32 1)
store i32 %66, i32* %18
%67 = load i32, i32* %17
%68 = load i32, i32* %18
%69 = call i32 @vlistDefTaxis(i32 %67, i32 %68)
%70 = getelementptr inbounds [14 x i8], [14 x i8]* %2, i64 0, i64 0
%71 = load i32, i32* %3
%72 = call i32 @streamOpenWrite(i8* %70, i32 %71)
store i32 %72, i32* %9
%73 = load i32, i32* %9
%74 = icmp slt i32 %73, 0
br i1 %74, label %75, label %83
75: ; preds = %0
%76 = load i32, i32* @stderr
%77 = getelementptr inbounds [14 x i8], [14 x i8]* %2, i64 0, i64 0
%78 = call i32 @fprintf(i32 %76, i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str, i64 0, i64 0), i8* %77)
%79 = load i32, i32* @stderr
%80 = load i32, i32* %9
%81 = call i8* @cdiStringError(i32 %80)
%82 = call i32 @fprintf(i32 %79, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), i8* %81)
store i32 -1, i32* %1
br label %93
83: ; preds = %0
%84 = load i32, i32* %9
%85 = load i32, i32* %17
%86 = call i32 @streamDefVlist(i32 %84, i32 %85)
%87 = load i32, i32* %9
%88 = call i32 @streamDefTimestep(i32 %87, i32 0)
%89 = load i32, i32* %9
%90 = load i32, i32* %8
%91 = load double*, double** %6
%92 = call i32 @streamWriteVar(i32 %89, i32 %90, double* %91, i32 0)
store i32 0, i32* %1
br label %93
93: ; preds = %83, %75
%94 = load i32, i32* %1
ret i32 %94
}

LLVM IR (-O2):
@__const.main.fname = [14 x i8] c"test_ens.grb2\00"
@stderr = global i32 0
@.str = [19 x i8] c"Open failed on %s\0A\00"
@.str.1 = [4 x i8] c"%s\0A\00"
define i32 @main() {
%1 = alloca [14 x i8]
%2 = alloca i32
%3 = alloca i32
%4 = alloca i32
%5 = getelementptr inbounds [14 x i8], [14 x i8]* %1, i64 0, i64 0
%6 = bitcast i32* %2 to i8*
%7 = bitcast i32* %3 to i8*
%8 = bitcast i32* %4 to i8*
%9 = tail call i64 @malloc(i64 5184)
%10 = inttoptr i64 %9 to double*
%11 = tail call i32 @memset(double* %10, i32 0, i64 5184)
%12 = tail call i32 @gridCreate(i32 2, i32 648)
%13 = tail call i32 @gridDefXsize(i32 %12, i32 36)
%14 = tail call i32 @gridDefYsize(i32 %12, i32 18)
%15 = tail call i32 @zaxisCreate(i32 0, i32 1)
%16 = tail call i32 @institutDef(i32 252, i32 0, i32* null, i32* null)
%17 = tail call i32 (...) @vlistCreate()
%18 = tail call i32 @vlistDefVar(i32 %17, i32 %12, i32 %15, i32 1)
%19 = tail call i32 @vlistDefVarEnsemble(i32 %17, i32 %18, i32 1, i32 2, i32 3)
%20 = call i32 @vlistInqVarEnsemble(i32 %17, i32 %18, i32* %2, i32* %3, i32* %4)
%21 = call i32 @vlistDefInstitut(i32 %17, i32 %16)
%22 = call i32 @taxisCreate(i32 1)
%23 = call i32 @vlistDefTaxis(i32 %17, i32 %22)
%24 = call i32 @streamOpenWrite(i8* %5, i32 2)
%25 = icmp slt i32 %24, 0
br i1 %25, label %26, label %32
26: ; preds = %0
%27 = load i32, i32* @stderr
%28 = call i32 @fprintf(i32 %27, i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str, i64 0, i64 0), i8* %5)
%29 = load i32, i32* @stderr
%30 = call i8* @cdiStringError(i32 %24)
%31 = call i32 @fprintf(i32 %29, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), i8* %30)
br label %36
32: ; preds = %0
%33 = call i32 @streamDefVlist(i32 %24, i32 %17)
%34 = call i32 @streamDefTimestep(i32 %24, i32 0)
%35 = call i32 @streamWriteVar(i32 %24, i32 %18, double* %10, i32 0)
br label %36
36: ; preds = %32, %26
%37 = phi i32 [ -1, %26 ], [ 0, %32 ]
ret i32 %37
}