NCAR / ncl

The NCAR Command Language (NCL) is a scripting language for the analysis and visualization of climate and weather data.

Home Page:http://www.ncl.ucar.edu

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ncl installation on Mac with M1 chip and arm64 machine

email-lhe opened this issue · comments

Hi,

I'm using a new Mac with M1 chip and arm64 machine, while the precompiled ncl was based on old compilers are not eligible for new Mac that can't install old version compilers. I tried to compile it using new compilers on my Mac, a lot of issues came up because of updates of compilers. I wonder whether anyone has successfully installed ncl on Mac with M1 chip and arm64 machine and willing to share the precompiled code or the experience, so more people with new Macs can have access to it.

Some of my issues are about missing header files, even I have reinstalled the command line tools for several times.

/usr/X11R6/include/cairo/cairo-ft.h:46:10: fatal error: ft2build.h: No such file or directory
46 | #include <ft2build.h>

hdf.c:54:10: fatal error: hdf.h: No such file or directory
54 | #include <hdf.h>

/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk/usr/include/signal.h:69:42: error: 'NSIG' undeclared here (not in a function)
69 | extern __const char *__const sys_signame[NSIG];
| ^~~~

udunitsW.c:5:10: fatal error: udunits2.h: No such file or directory
5 | #include <udunits2.h>

NclGRIB2.h:1:10: fatal error: grib2.h: No such file or directory
1 | #include <grib2.h>

NclApi.c:39:10: fatal error: netcdf.h: No such file or directory
39 | #include <netcdf.h>

udunitsW.c:5:10: fatal error: udunits2.h: No such file or directory
5 | #include <udunits2.h>

LDFLAGS="-L/usr/local/opt/freetype/lib -L/usr/local/opt/libpng/lib" CPPFLAGS="-I/usr/local/opt/freetype/include -I/usr/local/opt/libpng/include -I/usr/local/opt/freetype/include/freetype2" pip install matplotlib

LDFLAGS="-L/opt/X11/lib -L/usr/local/opt/libpng/lib" CPPFLAGS="-I/opt/X11/include/freetype2"

I would appreciate any help, thanks in advance.

Best,
Lynn

@email-lhe Did you have any success with this? I managed to at least compile the ncar graphics libraries, which I wanted for an old fortran plotting program. NCL works fine in emulation, but I'll see if I can get that to compile, as well (without hdf4 and some other options for now). The freetype error is fixed by adding it to the include paths (e.g., the Darwin_Arm config file in my fork)

My fork is https://github.com/MicroTed/ncl.git branch apple-arm64

I installed most of the dependencies with homebrew, and am using gcc-12 (also from homebrew). gcc apparently does not compile using xcode 14, so I'm using 13.4.1. I have netcdf4 compiled separately (netcdf-4.9.0).

It built an ncl executable, but that hits a seg fault somewhere quickly and fails.

Macports is reportedly building M1/arm64 versions from source. You might give that a try. If it works, please let us know, including your OS and Xcode versions.

https://ports.macports.org/port/ncarg/details/

Thanks for the news on that. I tried installing it on my M1 macbook pro. It compiles and creates arm64 binaries:

/opt/local/bin/ncl: Mach-O 64-bit executable arm64

but ncl gives a seg fault:

% ncl gsun01n.ncl
Copyright (C) 1995-2019 - All Rights Reserved
University Corporation for Atmospheric Research
NCAR Command Language Version 6.6.2
The use of this software is governed by a License Agreement.
See http://www.ncl.ucar.edu/ for more details.
Segmentation fault: 11

The libraries might work, e.g., for linking to fortran, but I haven't tried that yet (and that part was working before, too).

It's really just the calling fortran from C that needs help at this point. That is the source of the seg fault because the fortran side (CPNUMB) thinks a string is a lot longer than it really is and tries to initialize it. I haven't had time to learn how to fix that.

-- Ted

Macports is reportedly building M1/arm64 versions from source. You might give that a try. If it works, please let us know, including your OS and Xcode versions.

https://ports.macports.org/port/ncarg/details/

FYI, I appear to have successfully built an arm64 version of NCL using MacPorts. No extensive testing, but can generate graphics successfully using some of the sample scripts. I have similar issues as @MicroTed with homebrew. Did not try building from source.

% file /opt/local/bin/ncl
/opt/local/bin/ncl: Mach-O 64-bit executable arm64

with

export NCARG_ROOT=/opt/local
## Did not need this after switch to bash + reboot
## export DISPLAY=:0.0

in my .profile.

Process for me was simple, install MacPorts following instructions here and then:

sudo port install ncarg

Took about ~15-20 minutes.

MacOS 13.2.1
M1 Max

I am the maintainer of ncarg in MacPorts. Thanks to @MicroTed and my student I am aware of segfault. I ran all the examples and found that text, colour bars, and maps works, but not xy and contour plots. ncargex seems to work so it should be a problem with NCL or depending libraries. I still get segfault even with the workaround suggested by @MicroTed and am investigating the issue.

I got segfault with C/Fortran as well when hlu is used. The failure occurs when NhlCreate() is called at line 151 in xy01c.c with NhlxyPlotClass. ni/src/lib/hlu/XyPlot.c does not seem to call cpnumb at least directly. https://www.ncl.ucar.edu/Applications/BasicExamples/XyPlot/xy01.shtml

A minimum example in NCL would be:

begin
  wkn = "xy"
  wks = gsn_open_wks("x11", wkn)
  plot_object = create wkn xyPlotClass wks
  end create
end

I built ncl on FreeBSD arm64/UTM and had same error. The stack trace in the dumped core indicates an issue with len_trim.

#0  0x00000000433798a8 in _gfortran_string_len_trim () from /usr/local/lib/gcc12/libgfortran.so.5

Yes, I can reproduce I get the same behavior @tenomoto notes. NCL compiles and runs some scripts/code fine but then segfaults elsewhere. Using xy_2.ncl example...

$ ncl xy_2.ncl 
 Copyright (C) 1995-2019 - All Rights Reserved
 University Corporation for Atmospheric Research
 NCAR Command Language Version 6.6.2
 The use of this software is governed by a License Agreement.
 See http://www.ncl.ucar.edu/ for more details.
(0)	data created, generating xy plot
Segmentation fault: 11

@tenomoto, please show more of that stack trace. Rebuild ncarg with -g, if necessary to add ncarg symbols to the stack trace, so that we can better understand the context. Len_trim is called only from fortran code, so this should be traceable back into ncarg source code.

I haven't tried on macOS, but on FreeBSD len_trim is everything I get even with -g option.

Okay. I do not find a direct call to len_trim, anywhere in NCL 6.6.2 source code, or in current Macports patches. Either it is called by a dependency, or else the stack or execution sequence is broken.

Is it the same as calling 'len', e.g., len(cbuf)? Although I found that it returned a faulty value, the seg fault occured when cpnumb tried to set cbuf to blanks: cbuf=' ' or cbuf(1:lbuf)=' ' (with faulty lbuf from len)

@email-lhe Did you have any success with this? I managed to at least compile the ncar graphics libraries, which I wanted for an old fortran plotting program. NCL works fine in emulation, but I'll see if I can get that to compile, as well (without hdf4 and some other options for now). The freetype error is fixed by adding it to the include paths (e.g., the Darwin_Arm config file in my fork)

My fork is https://github.com/MicroTed/ncl.git branch apple-arm64

I installed most of the dependencies with homebrew, and am using gcc-12 (also from homebrew). gcc apparently does not compile using xcode 14, so I'm using 13.4.1. I have netcdf4 compiled separately (netcdf-4.9.0).

It built an ncl executable, but that hits a seg fault somewhere quickly and fails.

Sorry for the late response. Not yet. I used python instead.

Is it the same as calling 'len', e.g., len(cbuf)? ...

No, len() returns the declared length of a fortran character string. Len_trim() returns the string length, minus any trailing blanks. It is possible that len_trim() would call len() internally, but not the reverse.

If len(cbuf) returned a faulty value that exceeded the string length, then cbuf(1:lbuf)=' ' would possibly cause seg fault. However, bad value from len(cbuf) is concerning by itself.

I believe it only happens when C code passes the string to a Fortran subroutine, and the fortran gets an incorrect length. If len_trim tries to test the string for trailing blanks and also has a bad length, then it would go out of bounds?

Ted, the short answer is potentially yes, that could cause an out of bounds string reference. I have trouble following this, because as I already said, I do not find any len_trim references anywhere in NCL source.

If you could point me to a more specific scenario, I could try interpreting the NCL source code. I do not have access to an arm64 system to run my own testing.

NCL internally uses both cfortran and iftran, both obsolescent systems for extending fortran 77. Neither has been touched since the advent of Mac M1. This is fertile ground for systemic problems porting to M1/arm.

If I run the example given by @tenomoto with the macports compiled ncl (i.e., on M1), I get a traceback through cpnumb. So maybe gfortran uses len_trim as a generic for len? Or for some other string operation, perhaps. But when I compiled my own from source, it didn't fault on the len function itself. I haven't used lldb very much, and I'm not sure I can get the point in cpnumb where it crashes.

(lldb) thread backtrace
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x8100645191)
  * frame #0: 0x0000000103385878 libgfortran.5.dylib`_gfortran_string_len_trim + 84
    frame #1: 0x00000001004134e4 ncl`cpnumb_ + 132
    frame #2: 0x000000010038a7fc ncl`_NhlGetScaleInfo + 200
    frame #3: 0x000000010032a120 ncl`AutoComputeMajorTickMarks + 284
    frame #4: 0x0000000100326be0 ncl`ComputeTickInfo + 440
    frame #5: 0x0000000100320528 ncl`TickMarkInitialize + 1696
    frame #6: 0x0000000100302bf0 ncl`CallInitialize + 112
    frame #7: 0x0000000100301b48 ncl`_NhlCreate + 1152
    frame #8: 0x0000000100302a0c ncl`CreateChild + 584
    frame #9: 0x0000000100302ad4 ncl`_NhlALCreateChild + 124
    frame #10: 0x000000010036a0a0 ncl`ManageTickMarks + 3012
    frame #11: 0x000000010036906c ncl`ManageAnnotations + 252
    frame #12: 0x0000000100364b1c ncl`PlotManagerInitialize + 712
    frame #13: 0x0000000100302bf0 ncl`CallInitialize + 112
    frame #14: 0x0000000100301b48 ncl`_NhlCreate + 1152
    frame #15: 0x0000000100302a0c ncl`CreateChild + 584
    frame #16: 0x0000000100302ad4 ncl`_NhlALCreateChild + 124
    frame #17: 0x00000001003689e8 ncl`_NhlManageOverlay + 540
    frame #18: 0x0000000100377eb8 ncl`XyPlotChanges + 380
    frame #19: 0x0000000100377284 ncl`XyPlotInitialize + 1376
    frame #20: 0x0000000100302bf0 ncl`CallInitialize + 112
    frame #21: 0x0000000100301b48 ncl`_NhlCreate + 1152
    frame #22: 0x0000000100301e58 ncl`NhlCreate + 140
    frame #23: 0x000000010010e528 ncl`_NclCreateHLUObjOp + 1044
    frame #24: 0x00000001001023dc ncl`CallCREATE_OBJ_OP + 504
    frame #25: 0x0000000100108178 ncl`_NclExecute + 292
    frame #26: 0x000000010000b288 ncl`yyparse + 3208
    frame #27: 0x00000001000075fc ncl`NclDriver + 2536
    frame #28: 0x0000000100003ee4 ncl`main + 12
    frame #29: 0x0000000101aa508c dyld`start + 520

I have 6.6.2 working via rosetta2 on my M1 using a precompiled binary and some x86 libraries I brought over from another machine so this is less pressing for me. However, I'm happy to help debug, although my arm64 NCL is built using MacPorts (i.e., someone would need to tell me how to re-build with a -g flag ;) )

However, a simple xy script (below) gives me a similar trace to @MicroTed.

(lldb) target create "/opt/local/bin/ncl"
Current executable set to '/opt/local/bin/ncl' (arm64).
(lldb) settings set -- target.run-args  "xy_2.ncl"
(lldb) run
Process 7256 launched: '/opt/local/bin/ncl' (arm64)
 Copyright (C) 1995-2019 - All Rights Reserved
 University Corporation for Atmospheric Research
 NCAR Command Language Version 6.6.2
 The use of this software is governed by a License Agreement.
 See http://www.ncl.ucar.edu/ for more details.
(0)	data created, generating xy plot
Process 7256 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x81006451b9)
    frame #0: 0x000000010324d8d8 libgfortran.5.dylib`_gfortran_string_len_trim + 84
libgfortran.5.dylib`:
->  0x10324d8d8 <+84>: ldrsb  w5, [x4, x3]
    0x10324d8dc <+88>: cmp    w5, #0x20
    0x10324d8e0 <+92>: b.eq   0x10324d8ec               ; <+104>
    0x10324d8e4 <+96>: add    x0, x2, #0x1
Target 0: (ncl) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x81006451b9)
  * frame #0: 0x000000010324d8d8 libgfortran.5.dylib`_gfortran_string_len_trim + 84
    frame #1: 0x000000010041350c ncl`cpnumb_ + 132
    frame #2: 0x000000010038a824 ncl`_NhlGetScaleInfo + 200
    frame #3: 0x000000010032a148 ncl`AutoComputeMajorTickMarks + 284
    frame #4: 0x0000000100326c08 ncl`ComputeTickInfo + 440
    frame #5: 0x0000000100320550 ncl`TickMarkInitialize + 1696
    frame #6: 0x0000000100302c18 ncl`CallInitialize + 112
    frame #7: 0x0000000100301b70 ncl`_NhlCreate + 1152
    frame #8: 0x0000000100302a34 ncl`CreateChild + 584
    frame #9: 0x0000000100302afc ncl`_NhlALCreateChild + 124
    frame #10: 0x000000010036a0c8 ncl`ManageTickMarks + 3012
    frame #11: 0x0000000100369094 ncl`ManageAnnotations + 252
    frame #12: 0x0000000100364b44 ncl`PlotManagerInitialize + 712
    frame #13: 0x0000000100302c18 ncl`CallInitialize + 112
    frame #14: 0x0000000100301b70 ncl`_NhlCreate + 1152
    frame #15: 0x0000000100302a34 ncl`CreateChild + 584
    frame #16: 0x0000000100302afc ncl`_NhlALCreateChild + 124
    frame #17: 0x0000000100368a10 ncl`_NhlManageOverlay + 540
    frame #18: 0x0000000100377ee0 ncl`XyPlotChanges + 380
    frame #19: 0x00000001003772ac ncl`XyPlotInitialize + 1376
    frame #20: 0x0000000100302c18 ncl`CallInitialize + 112
    frame #21: 0x0000000100301b70 ncl`_NhlCreate + 1152
    frame #22: 0x0000000100301e80 ncl`NhlCreate + 140
    frame #23: 0x000000010010e550 ncl`_NclCreateHLUObjOp + 1044
    frame #24: 0x0000000100102404 ncl`CallCREATE_OBJ_OP + 504
    frame #25: 0x00000001001081a0 ncl`_NclExecute + 292
    frame #26: 0x000000010010e048 ncl`_NclFuncCallOp + 56
    frame #27: 0x00000001000fde70 ncl`CallFUNC_CALL_OP + 124
    frame #28: 0x0000000100108260 ncl`_NclExecute + 484
    frame #29: 0x000000010010e048 ncl`_NclFuncCallOp + 56
    frame #30: 0x00000001000fde70 ncl`CallFUNC_CALL_OP + 124
    frame #31: 0x0000000100108260 ncl`_NclExecute + 484
    frame #32: 0x000000010000b2b0 ncl`yyparse + 3208
    frame #33: 0x0000000100007624 ncl`NclDriver + 2536
    frame #34: 0x0000000100003f0c ncl`main + 12
    frame #35: 0x000000018951be50 dyld`start + 2544
(lldb) 

Script for reference.

begin

 f     = addfile ("$NCARG_ROOT/lib/ncarg/data/cdf/uv300.nc","r")
 u     = f->U                                    ; get u data

 data      = new((/2,dimsizes(u&lat)/),float)

 data(0,:) = u(0,:,{82})
 data(1,:) = u(0,:,{-69})

 print("data created, generating xy plot")
 wks   = gsn_open_wks ("x11","xy")                 ; send graphics to PNG file

 res                   = True                      ; plot mods desired
 res@tiMainString      = "Two curve XY plot"       ; add title
 res@xyLineThicknesses = (/  1.0,   2.0/)          ; make second line thicker
 res@xyLineColors      = (/"blue","red"/)          ; change line color

 plot  = gsn_csm_xy (wks,u&lat,data,res) ; create plot

end

I went back to one of my 6.6.2 testing versions and got more info in the backtrace:

(lldb) frame select 1
This version of LLDB has no plugin for the language "fortran90". Inspection of frame variables will be limited.
frame #1: 0x000000010047b020 ncl`cpnumb_ at cpnumb.f:193:10
   190 	C
   191 	      LCX1=LEN(CEX1)
   192 	       write(0,*) 'cpnum: lcx1 = ',lcx1
-> 193 	      IF (CEX1(1:1).EQ.' ') LCX1=0
    	         ^
   194 	      LCX2=LEN(CEX2)
   195 	       write(0,*) 'cpnum: lcx2 = ',lcx2
   196 	      IF (CEX2(1:1).EQ.' ') LCX2=0

The write statement was obviously added for debugging, and, fwiw, the output was 'cpnum: lcx1 = 8233'
So apparently the IF test is where gfortran is calling len_trim as part of the evaluation (even though it is only checking the first character):

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x20)
  * frame #0: 0x0000000102f4f6dc libgfortran.5.dylib`_gfortran_string_len_trim.part.0 + 76
    frame #1: 0x000000010047b020 ncl`cpnumb_ at cpnumb.f:193:10
    frame #2: 0x00000001003d18dc ncl`_NhlGetScaleInfo(value=<unavailable>, div_pwr=0x000000016fdbb1cc, sig_digits=0x000000016fdbb1c8, entry_point=<unavailable>) at Format.c:1300:3

It has been a while since I looked at this. It could be that my little hack in cpnumb (noted in the PR) only worked if compiled with -g -O0 (overrides the default -O). But I don't recall for sure.
Anyway, I hope that is helpful.

I came across something that suggested the C code might need to declare the string length variables as 'long int', so in Format.c, if I change the two declarations of

int len1,len2,len3,len4;

to

long int len1,len2,len3,len4;
Then cpnumb gets the correct string lengths and there is no seg fault. I guess that when compiling on arm64, gfortran passes an 8-byte integer for the string length?
Perhaps just setting an appropriate preprocessing flag (e.g., arm64) to switch the declaration is all we need? I pushed an update to my ncl branch/PR so anyone can see if it also works on FreeBSD.

@MicroTed 's fix works fine! I only changed Format.c. The aarch64 architecture is LP64, i.e. int is 32 and long is 64 bits. I need to check the fix on Intel mac (x86_64) before I commit. I don't see why the same error does not arise on x86_64. On 32-bit architectures (LP32), int = long = 32 and the fix shouldn't cause any problems.

--- ni/src/lib/hlu/Format.c.orig	2019-02-28 08:44:39.000000000 +0900
+++ ni/src/lib/hlu/Format.c	2023-03-09 15:33:04.000000000 +0900
@@ -940,7 +940,7 @@
         NGCALLF(cpinrc,CPINRC)();
 
 	{
-		int len1,len2,len3,len4;
+		long len1,len2,len3,len4;
 		NGstring cex1_f;
 		NGstring cex2_f;
 		NGstring cex3_f;
@@ -1283,7 +1283,7 @@
         NGCALLF(cpinrc,CPINRC)();
 
 	{
-		int len1,len2,len3,len4;
+		long len1,len2,len3,len4;
 		NGstring cex1_f;
 		NGstring cex2_f;
 		NGstring cex3_f;

@tenomoto I don't know about gfortran, but I found this for Intel ifort:

By default, Intel® Fortran passes a hidden length argument for strings. The hidden length argument consists of an unsigned 4-byte integer (for systems based on IA-32 architecture) or unsigned 8-byte integer (for systems based on Intel® 64 architecture), always passed by value, added to the end of the argument list.

Was there any intel64 other than the itanium? Anyway, it sounds like it would still use 4-byte on regular intel processors, even if compiled -m64, so I assume gfortran does the same on x86?

@MicroTed, could you update your pull request #191?

The size of hidden argument is size_t with gfortran.
On both aarch64 and x86_64 the output of the following C code is

% ./a.out
int 4
long 8
size_t 8

This makes me wonder why ncl works without the fix.

#include <stdio.h>

int main(void)
{
  printf("int %lu\n", sizeof(int));
  printf("long %lu\n", sizeof(long));
  printf("size_t %lu\n", sizeof(size_t));
}

@MicroTed, could you update your pull request #191?

Sure. I had added the preprocessing flag to change it only for the arm64, just to be safe. Since you committed for macports, I assume it tested fine on intel mac.

FYI, I pulled @tenomoto's MacPorts update down, rebuilt, and was able to successfully run some of the tests we were having trouble with (e.g., xy plotting, etc.). However, there remains a segfault when setting a file. Originally noticed in when invoking ncl_convert2nc, but can repro in standalone scripts like below. Might be worth seeing if that is just on my end or consistent with other arm64 builds.

Script:

f = addfile("./cat_seed.nc","r")

U850 = f->U850(76:79,:,:)
V850 = f->V850(76:79,:,:)

scale = 1.e05
vrt   = U850                                      ; retain coordinates
vrt   = uv2vrG_Wrap(U850,V850) * scale
vrt@long_name = "vorticity"
vrt@units     = "scaled"

print("Getting ready to set file")
setfileoption("nc","Format","NetCDF4")
print("Done setting file")

system("/bin/rm -f simple.nc")   ; remove any pre-existing file
ncdf = addfile("simple.nc" ,"c")  ; open output netCDF file
fAtt               = True            ; assign file attributes
fAtt@title         = "NCL Simple Approach to netCDF Creation"
fAtt@source_file   =  "original-file.nc"
fAtt@Conventions   = "None"
fAtt@creation_date = systemfunc ("date")
fileattdef( ncdf, fAtt )            ; copy file attributes
filedimdef(ncdf,"time",-1,True)
ncdf->vrt = vrt

LLDB output:

(lldb) run
Process 47295 launched: '/opt/local/bin/ncl' (arm64)
 Copyright (C) 1995-2019 - All Rights Reserved
 University Corporation for Atmospheric Research
 NCAR Command Language Version 6.6.2
 The use of this software is governed by a License Agreement.
 See http://www.ncl.ucar.edu/ for more details.
(0)	Getting ready to set file
Process 47295 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x100000000)
    frame #0: 0x00000001000feb48 ncl`CallINTRINSIC_PROC_CALL + 288
ncl`CallINTRINSIC_PROC_CALL:
->  0x1000feb48 <+288>: str    x8, [x22]
    0x1000feb4c <+292>: ldr    x8, [x23]
    0x1000feb50 <+296>: add    x8, x8, #0x8
    0x1000feb54 <+300>: str    x8, [x23]
Target 0: (ncl) stopped.

Grepping through the source pops up a lot of C code which is (way) out of my wheelhouse.

@zarzycki, thank you for testing. Please run this test and show output. Run with ncl -Q:

setfileoption ("bin", "ReadByteOrder", "LittleEndian")
print ("Normal return")
exit

Sure. Same behavior.

$ ncl -Q test.ncl 
Segmentation fault: 11
(lldb) run -Q test.ncl
Process 52414 launched: '/opt/local/bin/ncl' (arm64)
Process 52414 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x100000000)
    frame #0: 0x00000001000feb48 ncl`CallINTRINSIC_PROC_CALL + 288
ncl`CallINTRINSIC_PROC_CALL:
->  0x1000feb48 <+288>: str    x8, [x22]
    0x1000feb4c <+292>: ldr    x8, [x23]
    0x1000feb50 <+296>: add    x8, x8, #0x8
    0x1000feb54 <+300>: str    x8, [x23]
Target 0: (ncl) stopped.

In case it matters, my "hacked" rosetta binary (i.e., a precompiled binary pulled with gcc@7 libs from a working intel Mac) returns normally with the above test.

All right. This setfileoption problem might be the same as Macports #64361, reported on Intel macs, not M1.

@zarzycki, what happens if you comment out the setfileoption line in your last test? Does it successfully write simple.nc with netcdf-3 format?

@zarzycki, what happens if you comment out the setfileoption line in your last test? Does it successfully write simple.nc with netcdf-3 format?

Yes.

$ file /opt/local/bin/ncl
/opt/local/bin/ncl: Mach-O 64-bit executable arm64
$ ncl -Q plot_seed.ncl 
$
$ ls -nrt simple.nc
-rw-r--r--  1 503  20    1048120 Mar 11 14:50 simple.nc

All right. This appears to prove some basic M1/arm64 functionality such as read and write netcdf-3, basic command execution, and some graphics as you showed earlier. That is a good start. I do not have any more insights on the setfileoption problem at this time.

@Dave-Allured, FYI, I ran your short script with no error:

% ncl -Q setfile.ncl
(0) Normal return

(M1, Monterey)

I have been trying to install NCL using Conda on Mac with M2 chip but no luck yet. But have not tried using Macports (https://ports.macports.org/port/ncarg/). Just wondering if there is a get around to fix the issue. I have codes written in NCL earlier that are not converted to Python yet. So, it will be a great help if someone found a fix yet.
Thanks,
Mahesh