Wave Check Compilation

0 views
Skip to first unread message

Peñen Tegtmeier

unread,
Aug 3, 2024, 4:34:42 PM8/3/24
to tronatsepol

It is typical in C++, particularly when dealing with templates, to employ techniques that prevent some particular piece of code from being compiled. As these can get convoluted, what is the best way to ensure that particular pieces of code do indeed generate compiler errors?

Do it in the similar way compiler tests are written. You will have a bit of testing code in some scripting language (shell, perl, tcl etc.) that will run compiler on given snippets of code and check whether the right ones compiled and the right ones did not.

Below, I check if overloads to the function func exist in static assertions, when used with a test framework, the boolean should be used on one of the run time tests in order to not block the other tests from compiling:

I recently tried tried to do a similar thing for a project in which I can only use c++17. In my code I also check if the function's return type matches the caller's expectations. Aside from some limitations regarding the non-type template parameters, a similiar thing can be achieved as demonstrated below. In this case I could not enfroce double as input to the overload, due to the implicit conversion, applies_to_func(void, int, int) will evaluate to true in the code snipplet below.

You would have to rely on an external framework to run a set of compilation tests, e.g. makefiles, or hudson jobs and check for either compiler output or compiler artifacts. If the compilation is supposed to fail then there should not be an object file for the file under compilation. I am guessing you could write a plugin for hudson to do that or a simple batch script that runs a makefile that compiles all the testfiles that should fail or succeed and flag successes or failures accordingly.

In the simplest case you would just check for the existance of the '.o' file to see whether your test succeeded, in more complex cases you might want to look at the compiler output and verify that the error that is produce concurs with the error that you are expecting. That would depend on the compiler that you are using.

You might want to check out metatest - Unit testing framework for C++ template metaprograms (author's original post to the Boost mailing list). Get it here.
Publications related to the libraries here.

[This is a variant of @mutableVoid's answer above, but a little more explicit on two things that I had to think about a little. It concerns only concepts, which is what I wanted to get under test, so it only applies to C++20 onwards].

Or it could be more complex, in this case, a concept that checks that type T has a size function that returns the type's size_type (and you can add more requirements to this "compound requirement", say, that it has a [] operator):

The Arbitrary Waveform Generator functionality is realized using field-programmable gate array (FPGA) technology and is available on multiple instruments types, like the HDAWG or the SHFSG. Users can operate the AWG through a program called sequencer code, it defines which waveforms are played and in which order. The syntax of the LabOne AWG Sequencer programming language is based on C, but with a few simplifications.

LabOne provides the AWG module to compile and upload a sequencer program to the device. In zhinst-toolkit this module is also available. In addition the devices with AWG support also have helper function directly implemented in the node tree.

When uploading the sequencer code with load_sequencer_program as a string, zhinst-toolkit first compiles the the code into a binary elf format. After that it uploads the byte code to the device. One can also use the offline compiler directly or zhinst-toolkit to compile the sequence without an active device connection.

zhinst-toolkit uses by default the offline compiler provided by zhinst-core. If a feature or setting is not supported by the offline compiler (e.g. channel grouping on the HDAWG) the best way is to fallback to the awg module from Labone.

zhinst-toolkit also offers a class Sequence representing a LabOne Sequence. This class enables a compact representation of a sequence for a Zurich Instruments device. Although a sequencer code can be represented by a simple string this class offers the following advantages:

The waveform must be first defined in the sequence, either as placeholder (like in the sequencer code above) or as completely defined waveform with valid samples. In the first case, the compiler will only allocate the required memory and the waveform content is loaded later. The waveform definition must specify the length and eventual presence of markers. This should be respected later when the actual waveform is loaded.

The waveform data can be uploaded directly in the native AWG waveform format through its respective node (/.../awgs/n/wavforms/wave/m) which is also accessible through zhinst-toolkit. For more information on the native AWG waveform format take a look at the awg section in the labone user manuals. zhinst-toolkit itself offers a second, more user friendly approach through the class called Waveforms.

The Waveform class is a mutable mapping, meaning it behaves similar to a Python dictionary. The key defines the waveform index and the value is the waveform data provided as a tuple. The waveform data consists of the following elements:

The waveform data can also be assigned via the helper function assign_waveform which converts the data into the same tuple as used above. Similar assign_native_awg_waveform can be used to assign already to a single native AWG format array converted waveform data to an index.

As already discussed the waveforms must be defined in the sequencer program before they can be uploaded to the device. In addition to convert the assigned waveforms to the native AWG format the Waveform class can also generate a sequencer code snippet that defineds the waveforms present in the Waveform object.

Additional meta information can be added to each waveform to customize the snippet output. The following meta information are supported: * name: The name of the waveform. If specified, the placeholder will be assigned to a variable that can be in the sequencer program. * output: Output configuration for the waveform.

The Waveforms object can also be added to a Sequence object. This allows a a more structured code and prevents uploading the wrong waveforms. It also allows an easy declaration of the waveforms in the sequencer code since the above explained code snippet is automatically added to the sequencer code (can be disabled)

The command table allows the sequencer to group waveform playback instructions with other timing-critical phase and amplitude setting commands in a single instruction within one clock cycle of 3.33 ns. The command table is a unit separate from the sequencer and waveform memory. Both the phase and the amplitude can be set in absolute and in incremental mode. Even when not using digital modulation or amplitude settings, working with the command table has the advantage of being more efficient insequencer instruction memory compared to standard sequencing. Starting a waveform playback with the command table always requires just a single clock cycle, as opposed to 2 or 3 when using a playWave instruction.

The command tables is specified in the JSON format and need to conform to a device specific schema. The user manuals explain in detail how the command table is structured and used. Similar to the Waveforms zhinst-toolkit offers a helper class for the command table usage called CommandTable.

Since the command table structure is defined in a JSON schema the CommandTable class requires this json schema as well. Either one stores a copy of it locally or it can be accessed in zhinst-toolkit through the function load_validation_schema

Command table validates the given arguments on the fly by default. The feature has overhead and can be turned off to improve production code runtimes. Disabling it is good especially when creating a large command table with multiple table indexes. In any case, the command table is always validated upon upload and the instruments itself checks again errors.

Often the limiting factor for an experiment is the delay of the device communication. If this is the case it is best trying to reduce the number of uploads. For the AWG core this means uploading everything in a single transaction.

If the sequences are particularly long, it worth to compile them in parallel. The ThreadPollExecutor will use a number of threads depending on the CPU core count. Differently from generic Python code, the seqc compiler can use multiple cores at the same time, if used correctly.

As long as the Delft3D 4 Suite graphical user interface (GUI) is not available in open source, we are happy to offer you a pre-compiled version free of charge. The package consists of installers for the GUI and pre- and post-processing tools as well as various manuals and tutorials.
The latest pre-compiled version of the Delft3D 4 GUI is available for Windows 64-bit only.

Currently the full source code is available of the Delft3D-FLOW, Delft3D-WAVE, Delft3D-WAQ (DELWAQ) and Delft3D-PART (DELPAR) engines under GPLv3 conditions. The source code of the post-processing tool QUICKPLOT is also available.

Subversion (SVN) is a version control software that allows users to download any version of the trunk or a branch. It gives full control on all changes, and has abilities like roll back, submit patches and manage access. See Subversion for more details.

After registration you will have access to the Subversion server, managing the open source code. Before downloading the code (step 2), you need to install a set of tools to be able to compile the code. The tools needed depend on your operating system.

Subversion client to communicate with the Subversion server. You are free to use other clients, but our documentation is based on TortoiseSVN. The plain Subversion client is also an option and works identical to the Subversion client on Linux.

Step 6: Preparing the Visual Studio Solution files
Inside your trunk folder there should be a batch file called build.bat. Fill in "prepareonly=1" and "set config=delft3d4". It will build a delft3d4.sln solution file that can be used by Visual Studio to compile the source code. Double click it and a folder called build_delft3d4 should be created. Inside this folder you should find a file called delft3d4.sln.

c80f0f1006
Reply all
Reply to author
Forward
0 new messages